# options
options(stringsAsFactors = F)
knitr::opts_chunk$set(echo = TRUE, warning = FALSE, message = FALSE)
knitr::opts_knit$set(progress = FALSE)
# packages
# qtl mapping + mediation
library(intermediate) # "simecek/intermediate"
# library(intermediate2) # https://github.com/duytpm16/intermediate2
library(qtl2) 
# # plotting
library(plotly)
library(ggpubr)
library(ggraph)
library(pheatmap)
library(cowplot)
library(ggbeeswarm)
library(GGally)
library(corrplot)
# annotations + general genomic things
#library(biomaRt)
library(TxDb.Mmusculus.UCSC.mm10.knownGene)
library(org.Mm.eg.db)
library(ChIPseeker)
library(GenomicRanges)
#library(ensimplR) # https://github.com/churchill-lab/ensimplR
library(qvalue)
library(LOLA)  

# data processing
library(pcaMethods) # pca
library(Hmisc) # rcorr
# library(WGCNA)
library(gprofiler2)
# set gprofiler version
set_base_url("http://biit.cs.ut.ee/gprofiler_archive3/e106_eg53_p16/")

# library(sva)
library(WebGestaltR)
library(readxl)
library(tidyverse)
select <- dplyr::select # I am adding this explicitly
rename <- dplyr::rename # I am adding this explicitly
library(downloadthis)
# setting path
library(here)
# get functions
source(here("_src/functions.R")) # source all the common functions



Figure 1A: Overview of data sets

knitr::include_graphics(here("Figure1A.png"))
Figure 1A: Nearly 200 embryonic stem cell lines were established from blastocysts of Diversity Outbred mice, and quantified using ATAC-seq, RNA-seq (Skelly et al., 2020), and multiplexed mass spectrometry; 163 lines have all three measures.

Figure 1A: Nearly 200 embryonic stem cell lines were established from blastocysts of Diversity Outbred mice, and quantified using ATAC-seq, RNA-seq (Skelly et al., 2020), and multiplexed mass spectrometry; 163 lines have all three measures.


Table S1.Quantitative proteomic analysis of DO mESCs.

Table containing normalized and filtered protein abundances (n = 7,432) across individual DO mESClines (n = 190) and DO mESC line details with experimental covariates sex and genotype at the Lifr locus.


Annotations for all proteins in our data set can be downloaded using the link below.

list(all.prots) %>% 
  downloadthis::download_this(
    output_name = "Protein annotations",
    output_extension = ".xlsx",
    button_label = "Download protein annotations as xlsx",
    button_type = "primary",
    has_icon = TRUE,
    icon = "fa fa-save"
  )



Figure 1B: Detection bias in proteomics

# get the list of protein coding genes with transcript abundance in DO mESCs
all.prot_coding.genes <-  all.genes %>% 
  filter( gene_biotype =="protein_coding")

# get average transcript abundance for all protein coding genes
mrna <- expr.esc_rna %>%
  as_tibble( rownames = "sampleid") %>%
  select( all.prot_coding.genes$ensembl_gene_id) %>% 
  summarize_all(.funs = mean, na.rm = T) %>% 
  pivot_longer( all.prot_coding.genes$ensembl_gene_id, 
                names_to = "ensembl_gene_id", 
                values_to = "avg_rna")

# annotate if the gene is found in the protein data by setting prot = TRUE/FALSE
# add average transcript abundance 
all.prot_coding.genes%>% 
  select(ensembl_gene_id, mgi_symbol,ensembl_gene_id) %>%
  mutate(prot = ifelse( (ensembl_gene_id %in% all.prots$ensembl_gene_id |
                           mgi_symbol %in% all.prots$mgi_symbol), TRUE, FALSE)) %>%
  left_join(., mrna) -> prop.data


  
  
# calculate the probability of a protein being present given its mRNA abundance
get_props <- function(dat) {
  prop.table <- c()
  for (i in c(1, 5, 10, 25, 50, 75, 100, 150, 200, 250, 300, 400, 500, 600, 700, 800, 800, 1000, 2000, 5000, 10000, 50000, 1e05)) {
    prop <- dat %>%
      mutate(mRNA = ifelse(avg_rna > i, "at least", "less than")) %>%
      count(mRNA, prot) %>%
      spread(prot, n) %>%
      mutate( `FALSE` = ifelse( is.na(`FALSE`), 0, `FALSE`),
              `TRUE` = ifelse( is.na(`TRUE`), 0, `TRUE`)) %>% # replace NAs in case there aren't any detected/undetected proteins
      filter( (`TRUE`+`FALSE` > 5)) %>% # filter to make sure each bin has at least 5 genes. 
      mutate(detection_probability = `TRUE` / (`FALSE` + `TRUE`))
    prop.temp <- prop %>%
      filter(mRNA == "at least") %>%
      select(detection_probability) %>%
      mutate(avg_rna = i)
    prop.table <- rbind(prop.table, prop.temp)
  }
  return(prop.table)
}

Figure1b_data <- get_props(prop.data) %>% 
  rename( `Probability of protein detection` = detection_probability,
          `Average transcript abundance` = avg_rna)
prob_plot <- Figure1b_data %>% 
  ggplot() +
  aes(x = `Average transcript abundance`, 
      y = `Probability of protein detection`) +
  geom_point(size = 4) +
  scale_x_log10( expand= expansion( mult = c(.1, .12))) +
  theme_pubclean(base_size = 12) +
  geom_line() +
  ylab("Probability of protein detection") +
  xlab("Average transcript abundance") +
  ylim(0.5, .95)+
  theme(
    axis.text = element_text( size = 12),
    axis.title = element_text( size = 12)
  )

ggarrange(prob_plot, 
          labels = "B", 
          font.label = list( size = 20))
Figure 1B: Protein detection rate is linked to transcript abundance. The probability of a gene to have protein abundance measurement given its average transcript abundance among 174 mESCs with both transcriptome and proteome data.

Figure 1B: Protein detection rate is linked to transcript abundance. The probability of a gene to have protein abundance measurement given its average transcript abundance among 174 mESCs with both transcriptome and proteome data.


Figure1b_data %>% 
  mutate_if( is.numeric, round ,2) %>% 
  create_dt()

Data used in Figure 1B.


Table S2. Over-representation analysis of detected and undetected proteins.

Over-represented biological processes and pathways in proteins detected in all samples, and protein coding genes with transcript abundance lacking protein abundance (undetected proteins) are listed. Details include the data source, term id, term name, term size, the number of intersecting proteins and the FDR for each term identified to be overrepresented in detected or undetected protein coding genes.

# get proteins expressed in all samples
expr.esc_prot.comp <- expr.esc_prot %>%
  as.data.frame() %>%
  select( all_of(all.prots$protein_id))  %>% 
  select_if(~ !any(is.na(.)))

# get the gene/protein details for proteins measured in ALL the samples
prots.detected <- all.prots %>% 
  filter(protein_id %in% colnames(expr.esc_prot.comp),
         gene_biotype== "protein_coding")

# over-representation analysis for proteins detected in all samples vs all proteins
g.prot.detected <- gost(
  query = prots.detected$mgi_symbol,
  organism = "mmusculus",
  domain_scope = "custom",
  custom_bg = all.prots$mgi_symbol,
  evcodes = TRUE,
  correction_method = "fdr"
)
g.prot.detected$result <- g.prot.detected$result %>% 
  filter(term_size < 600)

g.prot.detected$result %>% 
  select(
    `Data source` = source,
    `Term ID` = term_id,
    `Term Name` = term_name, 
    `Term size` = term_size, 
    `# of intersecting proteins` = intersection_size,
     FDR = p_value
    ) -> tables2_sheet1

# get proteins not detected although RNA is detected
all.genes %>% 
  filter( !ensembl_gene_id %in% all.prots$ensembl_gene_id & # not in protein data
            gene_biotype == "protein_coding") -> not.detected 

all.prot_coding.genes <-  all.genes %>% 
  filter( gene_biotype =="protein_coding")

g.prot.not.detected <- gost(
  query = not.detected$mgi_symbol,
  organism = "mmusculus",
  domain_scope = "custom",
  custom_bg = all.prot_coding.genes$mgi_symbol, 
  evcodes = TRUE,
  correction_method = "fdr"
)
g.prot.not.detected$result <- g.prot.not.detected$result %>% filter(term_size < 600)

g.prot.not.detected$result %>% 
  select(
    `Data source` = source,
    `Term ID` = term_id,
    `Term Name` = term_name, 
    `Term size` = term_size, 
    `# of intersecting proteins` = intersection_size,
     FDR = p_value
    ) -> tables2_sheet2



Figure S1A-C: Transcription factors show lower transcript and protein abundance than other genes

rna_detect_plot <- apply(na.omit(expr.esc_rna), 2, mean) %>%
  as.data.frame() %>%
  rownames_to_column() %>%
  left_join(., all.genes, by = c("rowname" = "ensembl_gene_id")) %>%
  filter(gene_biotype %in% c("protein_coding")) %>%
  mutate(detected = ifelse(rowname %in% all.prots$ensembl_gene_id, "Detected", "Not detected")) %>%
  ggplot() +
  aes(x = detected, y = `.`) +
  geom_boxplot(width = 0.2) +
  ylab("Average transcript abundance") +
  scale_y_log10( expand = expansion(mult =c(0.4,0.2))) +
  theme_pubclean(base_size = 18) +
  #ggtitle("Protein coding genes") +
  xlab("") +
  stat_compare_means(method = "anova",label.y=7.5)+
  stat_compare_means(method = "t.test",label.y=6.5)
  

tf_rna_plot <- apply(na.omit(expr.esc_rna), 2, mean) %>%
  as.data.frame() %>%
  rownames_to_column() %>%
  left_join(., all.genes, by = c("rowname" = "ensembl_gene_id")) %>%
    filter(gene_biotype %in% c("protein_coding")) %>%
  mutate(is_tf = ifelse( mgi_symbol %in% all.tfs$mgi_symbol, "TF", "Not a TF")) %>%
  ggplot() +
  aes(x = is_tf, y = `.`) +
  geom_boxplot(width = 0.2) +
  ylab("Average transcript abundance") +
  scale_y_log10( expand = expansion(mult =c(0.4,0.2))) +
  theme_pubclean(base_size = 18) +
  #ggtitle("Protein coding genes") +
  xlab("") +
  stat_compare_means(method = "anova",label.y=7.5)+
  stat_compare_means(method = "t.test",label.y=6.5)

tf_prot_plot <- apply((expr.esc_prot[,all.prots$protein_id]), 2, mean, na.rm=TRUE) %>%
  as.data.frame() %>%
  rownames_to_column() %>%
  left_join( ., all.prots, by = c("rowname" = "protein_id")) %>% 
  mutate(is_tf = ifelse( mgi_symbol %in% all.tfs$mgi_symbol, "TF", "Not a TF")) %>%
  ggplot() +
  aes(x = is_tf, y = `.`) +
  geom_boxplot(width = 0.2) +
  ylab("Average protein abundance") +
  theme_pubclean(base_size = 18) +
  #ggtitle("Protein coding genes") +
  xlab("") +
  scale_y_continuous( expand =expansion(mult =c(0.3,0.2))) +
  stat_compare_means(method = "anova", label.y=17)+
  stat_compare_means(method = "t.test",label.y=15.5)



detection_plot <- ggarrange(rna_detect_plot, 
                            tf_rna_plot,tf_prot_plot, 
                            nrow = 1, 
                            widths = c(0.7,0.7,0.7), 
                            labels = c("A","B","C"),
                            font.label = list( size = 20))

detection_plot
FigureS1: (A) Genes where protein abundance is detected have a significantly higher mean transcript abundance (One way ANOVA, followed by t-test). Average transcript abundance of protein coding genes (n = 12,732) that are detected (TRUE, n = 7,240) and not detected (FALSE, n = 5,492) in the proteomics data are plotted. (B, C) TFs show a significantly lower mean for both transcript and protein abundance in comparison to other genes (One way ANOVA, followed by t-test). Average transcript and protein abundance of protein coding genes that are transcription factors (TF) and not transcription factors (Not a TF) are plotted.

FigureS1: (A) Genes where protein abundance is detected have a significantly higher mean transcript abundance (One way ANOVA, followed by t-test). Average transcript abundance of protein coding genes (n = 12,732) that are detected (TRUE, n = 7,240) and not detected (FALSE, n = 5,492) in the proteomics data are plotted. (B, C) TFs show a significantly lower mean for both transcript and protein abundance in comparison to other genes (One way ANOVA, followed by t-test). Average transcript and protein abundance of protein coding genes that are transcription factors (TF) and not transcription factors (Not a TF) are plotted.



Figure 1C: Principal component analysis of the pluripotent proteome

# principal component analysis using pcaMethods::pca function.
pca.prot <- pca(object = expr.esc_prot, 
                            method = "svdImpute", 
                            scale = "uv", 
                            nPcs = 10, 
                            center = TRUE
                            )

# get values for Principal components
Figure1c_data <- scores(pca.prot) %>%
  as_tibble( rownames ="sampleid") %>% 
  left_join(covarTidy.esc_prot) %>%
  mutate(sex = ifelse(sex == "F", "Female", "Male")) %>%
  rename(
    `Sample ID` = sampleid, 
    Sex = sex
  ) 
Figure1c_data %>% 
  ggplot() +
  aes(x = PC1, y = PC2, col = Sex) +
  geom_point(size = 4, alpha = 0.7) +
  theme(
    axis.text = element_text(size = 18),
    axis.title = element_text(size = 20), 
    legend.text = element_text(size = 16), legend.title = element_text(size = 16)
  ) +
  xlab(paste0("PC1 (", round(pca.prot@R2[1], 3) * 100, "%)")) +
  ylab(paste0("PC2 (", round(pca.prot@R2[2], 3) * 100, "%)")) +
  theme_pubclean(base_size = 18) + 
  color_palette("npg")+
  fill_palette("npg")+
  xlim(-100,150)+
  ylim(-100,150)+
  facet_wrap(~Sex, strip.position = "right")+
  theme(
    strip.background = element_blank(),
    strip.text.x = element_blank()
  ) -> pca_plot

ggarrange(pca_plot, 
          labels = "C",
          font.label = list( size = 20))
Figure 1C: Principal component analysis reveals sex as a significant source of variation among DO mESC proteomes. PC1 and PC2 for 190 mESCs are plotted and colored by sex.

Figure 1C: Principal component analysis reveals sex as a significant source of variation among DO mESC proteomes. PC1 and PC2 for 190 mESCs are plotted and colored by sex.


The data used in plotting Figure1C can be downloaded using the link below.

list( Figure1c_data %>% 
        select(`Sample ID`, Sex, PC1, PC2)) %>% 
  downloadthis::download_this(
    output_name = "Figure1C data",
    output_extension = ".xlsx",
    button_label = "Download Figure1C data as xlsx",
    button_type = "primary",
    has_icon = TRUE,
    icon = "fa fa-save"
  )


Drivers of PC1

# get top drivers of PC1
loadings(pca.prot) %>%
  as_tibble( rownames = "protein_id") %>% 
  left_join( all.prots) %>% 
  select(mgi_symbol, gene_chr, PC1) %>%
  filter( abs(PC1) >= quantile(abs(PC1), 0.90))-> pc1.loadings # most contributing 10%

# PC1 drivers by chromosome

pc1.loadings %>% 
  group_by(gene_chr) %>%
  # count() %>%
  # arrange(desc(n)) %>%
  ggplot()+
  aes( x = gene_chr)+
  geom_bar()+
  theme_pubclean( base_size = 18)+
  xlab("Chr")
Chromosomal locations of the top 10% of proteins that contribute to PC1.

Chromosomal locations of the top 10% of proteins that contribute to PC1.


g.pc1 <- gost(query = pc1.loadings$mgi_symbol, 
              organism = "mmusculus", 
              domain_scope = "custom", 
              custom_bg = all.prots$mgi_symbol, 
              evcodes = TRUE,
              correction_method = "fdr")
g.pc1$result <- g.pc1$result %>% filter(term_size < 600)

g.pc1$result %>% 
   select(
    `Data source` = source,
    `Term ID` = term_id,
    `Term Name` = term_name, 
    `Term size` = term_size, 
    `# of intersecting proteins` = intersection_size,
     FDR = p_value
    ) %>%
  mutate_if( is.numeric, formatC, digits =2) %>% 
  create_dt()

Over-represented biological processes and pathways in PC1 drivers.


Figure S1D-E: Variation in protein abundance

expr.esc_prot %>%
  as_tibble(.) %>%
  summarise_all(list(~ mean(., na.rm = T))) %>% 
  pivot_longer( all.prots$protein_id,
                names_to = "protein_id",
                values_to ="mean.prot") %>% 
  ggplot() +
  aes(x = mean.prot) +
  geom_histogram(binwidth = 0.1) +
  xlab("Mean") +
  theme_pubclean(base_size = 18) -> p.mean.hist

expr.esc_prot %>%
  as_tibble(.) %>%
  summarise_all(list(~ var(., na.rm = T))) %>% 
  pivot_longer( all.prots$protein_id,
                names_to = "protein_id",
                values_to ="var") %>% 
  ggplot() +
  aes(x = var) +
  geom_histogram(binwidth = 0.01) +
  xlab("Variance") +
  theme_pubclean(base_size = 18) +
  scale_x_log10() -> p.var.hist

ggarrange(p.mean.hist, 
          p.var.hist, 
          nrow =1, 
          labels = c("D","E"),
          font.label = list( size = 18))
(D, E) Protein abundance is highly variable across DO mESCs. Histograms showing the mean abundance and variance per protein plotted for 7,342 proteins across 190 DO mESC lines.

(D, E) Protein abundance is highly variable across DO mESCs. Histograms showing the mean abundance and variance per protein plotted for 7,342 proteins across 190 DO mESC lines.


Sex effects on protein abundance

# updating the code to use anova followed by tukey's hsd:
expr.esc_prot %>%
  t() %>% 
  as_tibble(rownames = "protein_id") %>%
  filter( protein_id %in% all.prots$protein_id) %>% 
  pivot_longer( cols = rownames(expr.esc_prot),
                values_to = "protein_ab",
                names_to = "sampleid") %>% 
  left_join(., select(covarTidy.esc_prot, sampleid, sex)) %>% 
  group_by(protein_id) %>% 
  rstatix::anova_test( protein_ab ~ sex) %>% 
  rstatix::adjust_pvalue( method = "BH") %>% 
  rstatix::add_significance("p.adj") %>% 
  as_tibble() -> prot_sex_aov

# passing the full data to tukey's then filtering
expr.esc_prot %>%
  t() %>% 
  as_tibble(rownames = "protein_id") %>% 
  filter( protein_id %in% all.prots$protein_id) %>% 
  pivot_longer( cols = rownames(expr.esc_prot),
                values_to = "protein_ab",
                names_to = "sampleid") %>% 
  left_join(., select(covarTidy.esc_prot, sampleid, sex)) %>% 
  group_by(protein_id) %>% 
  rstatix::tukey_hsd(protein_ab ~ sex) %>% 
  filter( protein_id %in% (filter(prot_sex_aov, p.adj.signif != "ns"))$protein_id ) -> prot_sex_tukeys


# get the medians for later
expr.esc_prot %>%
  t() %>% 
  as_tibble(rownames = "protein_id") %>%
  filter( protein_id %in% all.prots$protein_id) %>% 
  pivot_longer( cols = rownames(expr.esc_prot),
                values_to = "protein_ab",
                names_to = "sampleid") %>% 
  left_join(., select(covarTidy.esc_prot, sampleid, sex)) %>% 
  group_by(protein_id,sex) %>% 
  summarize( med = median(protein_ab, na.rm =T)) %>% 
  pivot_wider( id_cols = "protein_id",
               names_from = "sex",
               values_from = "med")-> prot_sex_med
prot_sex_tukeys %>%
  left_join( all.prots) %>% 
  left_join( prot_sex_med) %>% 
  arrange(p.adj) %>%
  mutate_if( is.numeric, round, 2) %>%
  select(
    `Protein ID` = protein_id,
    `MGI Symbol`= mgi_symbol, 
    `Protein location (chr)` = gene_chr,
    `Female median`=`F`,
    `Male median`= M
   ) %>%
  create_dt()

Table of proteins showing a significant sex effect.



Figure 1D: Geneset variation analysis of the pluripotent proteome

library(GSVA)
library(GO.db)

# Preparing gene sets from GO
# reading in the GO + mgi downloaded from: http://www.informatics.jax.org/gotools/data/input/MGIgenes_by_GOid.txt
go_terms <- read_tsv( "http://www.informatics.jax.org/gotools/data/input/MGIgenes_by_GOid.txt") %>% 
  mutate( genes = str_split(genes, ",")) %>% 
  unnest() # separete the symbols, note the overlap: length(intersect(unique(go_terms$genes), all.prots$mgi_symbol) ) = 6757

slim_go_terms <- read_tsv( "http://www.informatics.jax.org/gotools/data/input/map2MGIslim.txt") %>% 
  select(-term) %>% 
  mutate( ONT = case_when( aspect == "P" ~  "BP",
                     aspect == "F" ~ "MF",
                     aspect == "C" ~ "CC"
                     )
          ) %>% 
  select(-aspect)

genesbygo <- split(go_terms$genes, go_terms$GO_id)

go_terms_annot <- go_terms %>%  
  select(GO_id) %>% 
  distinct() %>% 
  left_join( slim_go_terms %>%  select( GO_id, ONT) %>% distinct())

goannot_wdef <- AnnotationDbi::select(GO.db, keys= unique(go_terms$GO_id), columns=c("GOID","DEFINITION","ONTOLOGY","TERM")) %>%
  left_join( slim_go_terms, by=c("GOID"="GO_id")) %>% 
  mutate( ONTOLOGY = ONT) %>% 
  select(-ONT)

go_bp <- goannot_wdef %>% filter( ONTOLOGY == "BP") %>% 
  select(GOID) %>%  distinct()

# Run GSVA using protein abundance
expr.esc_prot_upd <- expr.esc_prot[, all.prots$protein_id]
colnames(expr.esc_prot_upd) <- all.prots$mgi_symbol
gsva_prot <- gsva(  expr = t(expr.esc_prot_upd),
                    genesbygo,
                    method ="gsva",
                    kcdf = "none",
                    min.sz = 5, 
                    max.sz = 1000,
                    mx.diff = TRUE)

# Run GSVA with complexes to complement the co-abundance analysis
genes_for_complex_gsva <- complex.genes %>%  
  enframe( "Complex Name","human_ids") %>%
  unnest(human_ids) %>% 
  left_join( complex.gene.list) %>% 
  filter( !is.na(protein_id)) %>% 
  select( `Complex Name` , protein_id)
gsva_complexes <- unique(genes_for_complex_gsva$`Complex Name`)
genes_by_complex <- split(genes_for_complex_gsva$protein_id, genes_for_complex_gsva$`Complex Name`)
gsva_prot_comp <-  gsva(  expr = t(expr.esc_prot[,all.prots$protein_id]),
                    genes_by_complex,
                    method ="gsva",
                    kcdf = "none",
                    min.sz = 5, 
                    max.sz = 1000,
                    mx.diff = TRUE)

# Run GSVA using transcript abundance
expr.esc_rna_upd <- expr.esc_rna[, all.genes$ensembl_gene_id]
colnames(expr.esc_rna_upd) <- all.genes$mgi_symbol
gsva_rna <- gsva(  expr = t(expr.esc_rna_upd),
                    genesbygo,
                    method ="gsva",
                    kcdf = "none",
                    min.sz = 5, 
                    max.sz = 1000,
                    mx.diff = TRUE)

# Annotation and statistical follow up using ANOVA + Tukey's on Protein results
covar.lifr  %>% 
  rename( top_muga = rowname ) %>% 
  left_join(sample.matches.all) %>% 
  select(sampleid, lifr_geno) %>% 
  inner_join(covarTidy.esc_prot) -> covar_lifr_upd

gsva_prot %>% 
  as_tibble(rownames = "Category") %>% 
  filter( Category %in% go_bp$GOID) %>% #filtering for BP
  rbind( as_tibble(gsva_prot_comp, rownames = "Category" )) %>% 
  # rbind( as_tibble(gsva_prot3, rownames = "Category" )) %>% 
  # rbind( as_tibble(gsva_prot4, rownames = "Category")) %>% 
  pivot_longer( cols = rownames(expr.esc_prot_upd),
                values_to = "Enrichment_Score",
                names_to = "sampleid") %>% 
  # add sexes + lifr genotypes
  left_join( covar_lifr_upd) -> gsva_results


gsva_results %>% 
  group_by( Category) %>% 
  rstatix::anova_test( Enrichment_Score ~ sex+lifr_geno+sex*lifr_geno) %>% 
  rstatix::adjust_pvalue(method = "BH") %>%
  rstatix::add_significance("p.adj") %>% 
  ungroup() -> aov_results 

aov_results %>% 
  as_tibble() %>% 
  filter( p.adj.signif != "ns" ) -> signif_eff_terms

# passing all to Tukey's with the full model
gsva_results %>% 
  group_by(Category) %>% 
  rstatix::tukey_hsd( Enrichment_Score ~ sex+lifr_geno+sex:lifr_geno) %>% 
  ungroup() %>% 
  as_tibble() %>% 
  left_join( goannot_wdef, by = c("Category" = "GOID")) -> results_tukey

# filtering for the ones that were significant in ANOVA + Tukey's
results_tukey %>% 
  filter( p.adj < 0.05) %>% 
  inner_join( ., select( signif_eff_terms, Category, term = Effect)) -> signif_results_tukey

# Annotation and statistical follow up using ANOVA + Tukey's on RNA results
gsva_rna %>% 
  as_tibble(rownames = "Category") %>% 
  filter( Category %in% go_bp$GOID) %>% #filtering for BP
  pivot_longer( cols = rownames(expr.esc_rna_upd),
                values_to = "Enrichment_Score",
                names_to = "sampleid") %>% 
  # add sexes + lifr genotypes
  left_join( covar_lifr_upd) -> gsva_rna_results

gsva_rna_results %>% 
  group_by( Category) %>% 
  rstatix::anova_test( Enrichment_Score ~ sex+lifr_geno+sex*lifr_geno) %>% 
  rstatix::adjust_pvalue( method = "BH") %>%
  rstatix::add_significance("p.adj") %>% 
  ungroup() -> gsva_rna_aov

gsva_rna_results %>% 
  group_by(Category) %>% 
  rstatix::tukey_hsd( Enrichment_Score ~ sex+lifr_geno+sex:lifr_geno) %>% 
  ungroup() %>% 
  as_tibble() %>% 
  left_join( goannot_wdef, by = c("Category" = "GOID")) -> gsva_rna_tukey

gsva_rna_aov %>% 
  as_tibble() %>% 
  filter( p.adj.signif != "ns" ) -> signif_eff_terms_rna

gsva_rna_tukey %>% 
  filter( p.adj < 0.05) %>% 
  inner_join( ., select( signif_eff_terms_rna, Category, term = Effect)) -> signif_results_tukey_rna
Figure1d_data <- gsva_results %>%
  filter( Category %in% c("GO:0006306", # DNA methylation
                          "GO:0006338", # Chromatin remodeling
                          "GO:0042254" # Ribosome biogenesis
                          )) %>%
  left_join( select(goannot_wdef, Category = GOID, TERM)) %>% 
  select( Category, TERM, sampleid, Enrichment_Score, sex, lifr_geno) %>% 
  left_join(
    signif_results_tukey %>% 
      filter( term =="sex") %>% 
      select(Category, p.adj, p.adj.signif )
  ) %>% 
  rbind(
       gsva_results %>%  
         filter( Category == "GO:0006471") %>%  # protein ADP-ribosylation
         left_join( select(goannot_wdef, Category = GOID, TERM)) %>% 
         select( Category, TERM, sampleid, Enrichment_Score, sex, lifr_geno) %>% 
         left_join(
           signif_results_tukey %>% 
             filter( term =="lifr_geno") %>% 
             select(Category, p.adj, p.adj.signif )
           )
       ) %>% 
  mutate( Enrichment_Score = round(Enrichment_Score, 2)) %>% 
  select( `GO ID` = Category, 
          `GO Term`=TERM, 
          Sample = sampleid, 
          `Enrichment Score`=Enrichment_Score, 
          Sex = sex, 
          `Lifr genotype`=lifr_geno, 
          `Significance`=p.adj.signif)
Figure1d_data %>% 
  ggplot()+
  aes( x = Sex,
       y = `Enrichment Score`,
       col = Sex)+
  geom_boxplot(width =0.2, size = 1.1)+
  #geom_jitter()+
  #geom_beeswarm(aes(col = sex))+
  theme_pubclean(base_size = 16)+
  stat_pvalue_manual( filter(signif_results_tukey,Category  == "GO:0006306", term == "sex"),
                      label = "{p.adj.signif}",
                      y.position = 0.85)+
  color_palette("npg")+
  ylab("Enrichment Score")+
  ggtitle("DNA Methylation")+
  xlab("")+
  ylim(-1,1)+
  theme(axis.text.x = element_text(size = 18),
        axis.text.y = element_text(size = 18),
        axis.title = element_text(size =18),
        plot.title = element_text(size =18, hjust = 0.5)) -> p_met

Figure1d_data %>% 
  ggplot()+
  aes( x = Sex,
       y = `Enrichment Score`,
       col = Sex)+
  geom_boxplot(width =0.2, size = 1.1)+
  #geom_jitter()+
  #geom_beeswarm(aes(col = sex))+
  theme_pubclean(base_size = 16)+
  stat_pvalue_manual( filter(signif_results_tukey,Category  == "GO:0006338", term == "sex"),
                      label = "{p.adj.signif}",
                      y.position = 0.85)+
  color_palette("npg")+
  ylab("Enrichment Score")+
  ggtitle("Chromatin remodeling")+
  xlab("")+
  ylim(-1,1)+
  theme(axis.text.x = element_text(size = 18),
        axis.text.y = element_text(size = 18),
        axis.title = element_text(size =18),
        plot.title = element_text(size =18, hjust = .5)) -> p_chrom

Figure1d_data %>% 
  ggplot()+
  aes( x = Sex,
       y = `Enrichment Score`,
       col = Sex)+
  geom_boxplot(width =0.2, size = 1.1)+
  #geom_jitter()+
  #geom_beeswarm(aes(col = sex))+
  theme_pubclean(base_size = 16)+
  stat_pvalue_manual( filter(signif_results_tukey,Category  == "GO:0042254", term == "sex"),
                      label = "{p.adj.signif}",
                      y.position = 0.85)+
  color_palette("npg")+
  ylab("Enrichment Score")+
  ggtitle("Ribosome biogenesis")+
  xlab("")+
  ylim(-1,1)+
  theme(axis.text.x = element_text(size = 18),
        axis.text.y = element_text(size = 18),
        axis.title = element_text(size =18),
        plot.title = element_text(size =18, hjust = .5)) -> p_ribo

gsva_results %>%
  filter( Category ==  "GO:0006471") %>%
  left_join( select(goannot_wdef, Category = GOID, TERM)) %>% 
  rename( `GO ID` = Category, 
          `GO Term`=TERM, 
          Sample = sampleid, 
          `Enrichment Score`=Enrichment_Score, 
          Sex = sex, 
          `Lifr genotype`=lifr_geno) %>% 
  ggplot()+
  aes( x = `Lifr genotype`,
       y =  `Enrichment Score`,
       col = `Lifr genotype`)+
  geom_boxplot(width =0.2, size = 1.1)+
  #geom_jitter()+
  #geom_beeswarm(aes(col = sex))+
  theme_pubclean(base_size = 16)+
  stat_pvalue_manual( filter(signif_results_tukey,Category  == "GO:0006471", term == "lifr_geno"),
                      label = "{p.adj.signif}",
                      y.position = c(0.85, 0.95))+
  color_palette("Dark2")+
  ylab("Enrichment Score")+
  ggtitle("Protein ADP-ribosylation")+
  xlab("")+
  labs(col ="LIFR")+
  ylim(-1,1)+
  theme(legend.position = "none",
        axis.text.x = element_text(size = 18),
        axis.text.y = element_text(size = 18),
        axis.title = element_text(size =18),
        plot.title = element_text(size =18, hjust = .5)) -> p_adp

left <- ggarrange(p_met,p_chrom, p_ribo, 
                  common.legend = TRUE, 
                  nrow = 1,
                  ncol = 3, 
                  legend = "none")

ggarrange(left, p_adp, 
          nrow=1, 
          widths = c(.8,0.4) , 
          labels = c("D"), 
          font.label = list( size = 20))
Figure 1D: Enrichment scores obtained from GSVA for Gene Ontology Biological Processes (GO:BP) showing significant differences between mESCs with different sexes and genotypes at the Lifr locus are plotted. GO:BP DNA methylation, chromatin remodeling and ribosome biogenesis show significantly higher enrichment in males in comparison to females and, protein ADP-ribosylation shows significantly higher enrichment in mESCs with at least one copy of the reference allele in comparison to ones carrying two copies of the alternative allele at the *Lifr* locus (two-way anova followed by Tukey’s HSD, `*: p value < 0.05, ****: p value < 0.00005`).

Figure 1D: Enrichment scores obtained from GSVA for Gene Ontology Biological Processes (GO:BP) showing significant differences between mESCs with different sexes and genotypes at the Lifr locus are plotted. GO:BP DNA methylation, chromatin remodeling and ribosome biogenesis show significantly higher enrichment in males in comparison to females and, protein ADP-ribosylation shows significantly higher enrichment in mESCs with at least one copy of the reference allele in comparison to ones carrying two copies of the alternative allele at the Lifr locus (two-way anova followed by Tukey’s HSD, *: p value < 0.05, ****: p value < 0.00005).


The data used in plotting Figure1D can be downloaded using the link below.

list(Figure1d_data) %>% 
  downloadthis::download_this(
    output_name = "Figure1D data",
    output_extension = ".xlsx",
    button_label = "Download Figure1D data as xlsx",
    button_type = "primary",
    has_icon = TRUE,
    icon = "fa fa-save"
  )


Table S3: Gene Set Variation Analysis results.

Biological processes and protein complexes that show significant differences between experimental groups (sex, Lifr genotype, or their interaction) in GSVA enrichment scores obtained from protein or transcript abundance are listed. The source of the significant effect (sex, Lifr genotype or their interaction) as well as the two groups being compared is included with the Tukey’s HSD estimate and the adjusted p-value for each term.

signif_results_tukey %>% 
  #left_join( ., goannot_wdef %>%  select(TERM, GOID) %>% distinct()) %>% 
  select(Effect= term, Category, TERM,group1, group2, estimate,p.adj) %>% 
  distinct() %>% 
  mutate( estimate= round(estimate,2),
          TERM = ifelse( Category %in% genes_for_complex_gsva$`Complex Name`, "Protein Complex", TERM)) %>% 
  mutate( 
    temp = TERM,
    TERM = ifelse( TERM =="Protein Complex" & !is.na(TERM), Category, TERM ),
    Category = ifelse( temp == "Protein Complex" & !is.na(TERM), temp, Category)
          ) %>%  
  arrange(estimate) %>% 
  select( 
    Effect, 
    `Term ID` = Category,
    `Term Name` = TERM,
    `Group 1`= group1,
    `Group 2`= group2,
    `Tukey's HSD estimate` = estimate, 
    `Adjusted p-value` = p.adj
    ) -> tables3_sheet1


signif_results_tukey_rna %>%
  #left_join( ., goannot_wdef %>%  select(TERM, GOID) %>% distinct()) %>% 
  select(Effect= term, Category, TERM,group1, group2, estimate,p.adj) %>% 
  distinct() %>% 
  mutate( estimate= round(estimate,2),
          TERM = ifelse( Category %in% genes_for_complex_gsva$`Complex Name`, "Protein Complex", TERM)) %>% 
  mutate( 
    temp = TERM,
    TERM = ifelse( TERM =="Protein Complex" & !is.na(TERM), Category, TERM ),
    Category = ifelse( temp == "Protein Complex" & !is.na(TERM), temp, Category)
          ) %>% 
  arrange(estimate) %>% 
  select( 
    Effect, 
    `Term ID` = Category,
    `Term Name` = TERM,
    `Group 1`= group1,
    `Group 2`= group2,
    `Tukey's HSD estimate` = estimate, 
    `Adjusted p-value` = p.adj
    ) -> tables3_sheet2


Over-representation analysis in proteins with high and low variation in abundance

var_prot <- expr.esc_prot %>%
  as_tibble(.) %>%
  summarise_all(list(~ var(., na.rm = T))) %>% 
  pivot_longer( all.prots$protein_id,
                names_to = "protein_id",
                values_to ="var") 

high.var.prots <- var_prot %>%  
  filter( var >= quantile(var, 0.95)) %>% 
  left_join( all.prots %>%  
               select( protein_id, mgi_symbol))

low.var.prots <- var_prot %>% 
  filter( var <= quantile(var, 0.05))%>% 
  left_join( all.prots %>%  
               select( protein_id, mgi_symbol))

g.high.var <- gost(
  query = high.var.prots$mgi_symbol,
  organism = "mmusculus",
  domain_scope = "custom",
  custom_bg = all.prots$mgi_symbol,
  evcodes = TRUE,
  correction_method = "fdr"
)
g.high.var$result <- g.high.var$result %>% filter(term_size < 600)

g.low.var <- gost(
  query = low.var.prots$mgi_symbol,
  organism = "mmusculus",
  domain_scope = "custom",
  custom_bg = all.prots$mgi_symbol,
  evcodes = TRUE,
  correction_method = "fdr"
)
g.low.var$result <- g.low.var$result %>% filter(term_size < 600)

g.high.var$result %>% 
  mutate( `Gene Set` = "High variation") %>% 
  select(`Gene Set`, `Term Name` = term_name, source, FDR = p_value, `Term size` = term_size, Intersection = intersection_size,term_id)  %>% 
  rbind(
    g.low.var$result %>%
      mutate( `Gene Set` = "Low variation") %>% 
       select(`Gene Set`, `Term Name` = term_name, source, FDR = p_value, `Term size` = term_size, Intersection = intersection_size, term_id) 
    ) %>% 
  select(
         `Gene Set`, 
    `Data source` = source,
    `Term ID` = term_id,
    `Term Name` , 
    `Term size` , 
    `# of intersecting proteins` = Intersection,
     FDR 
    ) %>% 
  mutate_if( is.numeric, formatC, digits =2) %>% 
  create_dt()

Over-represented biological processes and pathways in proteins with high (top 5th percentile) and low variation (bottom 5th percentile).


Figure S1F-G

# get proteins identified as part of "extracellular region"
ecm_genes <- tibble(mgi_symbol = unlist(str_split((g.high.var$result %>% filter(term_name %in% c("extracellular region", "extracellular matrix")))$intersection, ","))) %>%
  left_join(., all.prots)

# get proteins identified as REX1 targets 
rex1.genes <- tibble(mgi_symbol = unlist(str_split((g.low.var$result %>% filter(source == "TF"))$intersection[1], ","))) %>%
  left_join(., all.prots)

# get variance + mean by protein into a single data frame
mean_prot <- expr.esc_prot %>%
  as_tibble(.) %>%
  summarise_all(list(~ mean(., na.rm = T))) %>% 
  pivot_longer( all.prots$protein_id,
                names_to = "protein_id",
                values_to ="mean") 

var_mean_prot <- var_prot %>% 
  full_join( mean_prot) %>% 
  left_join( all.prots)
  
var_mean_prot %>% 
  ggscatter(., 
            x = "mean", 
            y = "var", 
            size = 3, 
            alpha = 0.5,
            col="gray",
            yscale = "log10",
            #xscale = "log10",
            show.legend.text = FALSE
            ) +
  xlab("Mean protein abundance") +
  ylab("Variance in protein abundance") +
  ggtitle("REX1 Target Proteins")+
  theme_pubclean(base_size = 18) + 
  rremove("legend") +
  geom_point(
    data =   filter( var_mean_prot, ensembl_gene_id %in% rex1.genes$ensembl_gene_id) ,
    col = "blue", alpha = 0.6, size = 3)+
  geom_point( data = filter(var_mean_prot, mgi_symbol == "Zfp42"), col = "purple", size = 4, alpha = 1)+
  geom_label( data = filter(var_mean_prot, mgi_symbol == "Zfp42") , label = "Rex1", nudge_x = .2, nudge_y = .2)  -> plot_rex1


var_mean_prot %>% 
  ggscatter(., 
            y = "var", 
            x = "mean", 
            size = 3, 
            alpha = 0.5,
            col="gray",
            yscale = "log10",
            #xscale = "log10",
            show.legend.text = FALSE
            ) +
  ylab("Variance in protein abundance") +
  xlab("Mean protein abundance") +
  theme_pubclean(base_size = 18) + 
  rremove("legend") +
  geom_point(
    data =   filter( var_mean_prot, ensembl_gene_id %in% c(ecm_genes$ensembl_gene_id)) ,
    col = "blue", alpha = 0.6, size = 3) +
  ggtitle("Extracellular Matrix Proteins")-> plot_ecm

ggarrange( plot_ecm, plot_rex1, nrow =1 ,
           labels = c("F","G"),
          font.label = list( size = 20)
        )
FigureS1: (F) Mean abundance and variance plotted for all proteins (gray) with proteins identified as part of `Extracellular region` and `ECM protein` GO Terms in most variable proteins (top 5th percentile %CV), in overrepresentation analysis, highlighted in blue. (G) Mean abundance and variance plotted for all proteins with proteins identified as `REX1 Target` in TRANSFAC database in least variable proteins (bottom 5th percentile %CV), in overrepresentation analysis, highlighted in blue and REX1 (Zfp42) highlighted in purple.

FigureS1: (F) Mean abundance and variance plotted for all proteins (gray) with proteins identified as part of Extracellular region and ECM protein GO Terms in most variable proteins (top 5th percentile %CV), in overrepresentation analysis, highlighted in blue. (G) Mean abundance and variance plotted for all proteins with proteins identified as REX1 Target in TRANSFAC database in least variable proteins (bottom 5th percentile %CV), in overrepresentation analysis, highlighted in blue and REX1 (Zfp42) highlighted in purple.

LS0tCnRpdGxlOiAiUGx1cmlwb3RlbnQgUHJvdGVvbWUiCm91dHB1dDoKICBodG1sX2RvY3VtZW50OgogICAgdG9jOiB0cnVlCiAgICB0b2NfZGVwdGg6IDQKICAgIHRvY19mbG9hdDogCiAgICAgIGNvbGxhcHNlZDogZmFsc2UKICAgICAgc21vb3RoX3Njcm9sbDogZmFsc2UKICAgIGRmX3ByaW50OiBwYWdlZAogICAgY29kZV9mb2xkaW5nOiBoaWRlCi0tLQoKYGBgez1odG1sfQo8c3R5bGU+CnAuY2FwdGlvbiB7CiAgZm9udC1zaXplOiAxZW07Cn0KPC9zdHlsZT4KYGBgCgpgYGB7ciBsb2FkX3BhY2thZ2VzLCB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCBlY2hvID0gVFJVRX0KIyBvcHRpb25zCm9wdGlvbnMoc3RyaW5nc0FzRmFjdG9ycyA9IEYpCmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSwgd2FybmluZyA9IEZBTFNFLCBtZXNzYWdlID0gRkFMU0UpCmtuaXRyOjpvcHRzX2tuaXQkc2V0KHByb2dyZXNzID0gRkFMU0UpCiMgcGFja2FnZXMKIyBxdGwgbWFwcGluZyArIG1lZGlhdGlvbgpsaWJyYXJ5KGludGVybWVkaWF0ZSkgIyAic2ltZWNlay9pbnRlcm1lZGlhdGUiCiMgbGlicmFyeShpbnRlcm1lZGlhdGUyKSAjIGh0dHBzOi8vZ2l0aHViLmNvbS9kdXl0cG0xNi9pbnRlcm1lZGlhdGUyCmxpYnJhcnkocXRsMikgCiMgIyBwbG90dGluZwpsaWJyYXJ5KHBsb3RseSkKbGlicmFyeShnZ3B1YnIpCmxpYnJhcnkoZ2dyYXBoKQpsaWJyYXJ5KHBoZWF0bWFwKQpsaWJyYXJ5KGNvd3Bsb3QpCmxpYnJhcnkoZ2diZWVzd2FybSkKbGlicmFyeShHR2FsbHkpCmxpYnJhcnkoY29ycnBsb3QpCiMgYW5ub3RhdGlvbnMgKyBnZW5lcmFsIGdlbm9taWMgdGhpbmdzCiNsaWJyYXJ5KGJpb21hUnQpCmxpYnJhcnkoVHhEYi5NbXVzY3VsdXMuVUNTQy5tbTEwLmtub3duR2VuZSkKbGlicmFyeShvcmcuTW0uZWcuZGIpCmxpYnJhcnkoQ2hJUHNlZWtlcikKbGlicmFyeShHZW5vbWljUmFuZ2VzKQojbGlicmFyeShlbnNpbXBsUikgIyBodHRwczovL2dpdGh1Yi5jb20vY2h1cmNoaWxsLWxhYi9lbnNpbXBsUgpsaWJyYXJ5KHF2YWx1ZSkKbGlicmFyeShMT0xBKSAgCgojIGRhdGEgcHJvY2Vzc2luZwpsaWJyYXJ5KHBjYU1ldGhvZHMpICMgcGNhCmxpYnJhcnkoSG1pc2MpICMgcmNvcnIKIyBsaWJyYXJ5KFdHQ05BKQpsaWJyYXJ5KGdwcm9maWxlcjIpCiMgc2V0IGdwcm9maWxlciB2ZXJzaW9uCnNldF9iYXNlX3VybCgiaHR0cDovL2JpaXQuY3MudXQuZWUvZ3Byb2ZpbGVyX2FyY2hpdmUzL2UxMDZfZWc1M19wMTYvIikKCiMgbGlicmFyeShzdmEpCmxpYnJhcnkoV2ViR2VzdGFsdFIpCmxpYnJhcnkocmVhZHhsKQpsaWJyYXJ5KHRpZHl2ZXJzZSkKc2VsZWN0IDwtIGRwbHlyOjpzZWxlY3QgIyBJIGFtIGFkZGluZyB0aGlzIGV4cGxpY2l0bHkKcmVuYW1lIDwtIGRwbHlyOjpyZW5hbWUgIyBJIGFtIGFkZGluZyB0aGlzIGV4cGxpY2l0bHkKbGlicmFyeShkb3dubG9hZHRoaXMpCiMgc2V0dGluZyBwYXRoCmxpYnJhcnkoaGVyZSkKIyBnZXQgZnVuY3Rpb25zCnNvdXJjZShoZXJlKCJfc3JjL2Z1bmN0aW9ucy5SIikpICMgc291cmNlIGFsbCB0aGUgY29tbW9uIGZ1bmN0aW9ucwpgYGAKCmBgYHtyIGxvYWRfYW5ub3RhdGVfb21pY3NfZGF0YSwgd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgcmVzdWx0cz0iaGlkZSIgLCBlY2hvID1GQUxTRX0KIyMjIyMgUHJvdGVpbiBkYXRhCiMgTm90ZSB0aGUgZW5zZW1ibCBwcm90ZWluIGlkJ3MgYXJlIGZyb20gdjk4CmxvYWQoaGVyZSgiLi4vcFFUTF93ZWJzaXRlL19kYXRhL0RPX21FU0NfcFFUTF9mb3JNYXBwaW5nX25vUG9seV92My5SRGF0YSIpKQpleHByWi5lc2NfcHJvdCA8LSBleHByWgpwcm9icy5lc2NfcHJvdCA8LSBnZW5vcHJvYnMKY292YXIuZXNjX3Byb3QgPC0gY292YXIKY292YXJUaWR5LmVzY19wcm90IDwtIGNvdmFyVGlkeQpraW5zaGlwX2xvY28uZXNjX3Byb3QgPC0ga2luc2hpcF9sb2NvCiMgSSBkb24ndCB3YW50IHRvIHVzZSB0aGUgcmFua1ogbm9ybWFsaXplZCB2ZXJzaW9uLiBsZXQncyBjbGVhbiB1cCB0aGUgcmF3IGRhdGEgZm9yIHVzZS4KcmF3LmV4cHIuZXNjX3Byb3QgPC0gcmF3LmV4cHIKZXhwci5lc2NfcHJvdCA8LSByYXcuZXhwcltyb3duYW1lcyhyYXcuZXhwcikgJWluJSByb3duYW1lcyhleHByWiksIGNvbG5hbWVzKHJhdy5leHByKSAlaW4lIGNvbG5hbWVzKGV4cHJaKV0KZXhwci5lc2NfcHJvdCA8LSBhcy5tYXRyaXgoZXhwci5lc2NfcHJvdCkKcm0oZXhwclosIGNvdmFyLCBjb3ZhclRpZHksIGtpbnNoaXBfbG9jbywgZ2Vub3Byb2JzLCByYXcuZXhwcikKIyMjIyMgUk5BIGRhdGEKIyBOb3RlIHRoZSBlbnNlbWJsIGdlbmUgaWQncyBhcmUgZnJvbSB2ODIKIyBOb3RlIHRoYXQgdGhlcmUgYXJlIDIwIGVuc2VtYmwgZ2VuZSBpZCdzIHRoYXQgZG9uJ3QgbWF0Y2ggYW55dGhpbmcgZXZlbiBpbiB2ODIuCmxvYWQoaGVyZSgiLi4vcFFUTF93ZWJzaXRlL19kYXRhL0RPX21FU0NfcGFpcmVkX2VRVExfZm9yTWFwcGluZy5SRGF0YSIpKQpyYXcuZXhwci5lc2Nfcm5hIDwtIGVzYy5yYXcuZXhwcgpleHByWi5lc2Nfcm5hIDwtIGVzYy5leHByWgpraW5zaGlwX2xvY28uZXNjX3JuYSA8LSBlc2Mua2luc2hpcF9sb2NvCnByb2JzLmVzY19ybmEgPC0gZXNjLnByb2JzCmNvdmFyLmVzY19ybmEgPC0gZXNjLmNvdmFyCmNvdmFyVGlkeS5lc2Nfcm5hIDwtIGNvdmFyVGlkeQpleHByQ29tQmF0LmVzY19ybmEgPC0gZXNjLmV4cHIuQ29tQmF0CmV4cHIuZXNjX3JuYSA8LSBleHBtMShleHByQ29tQmF0LmVzY19ybmEpICMgcmUtdHJhbnNmb3JtaW5nIHNpbmNlIHRoZSBkYXRhIHdhcyBsb2coeCsxKSBiZWZvcmUgY29tYmF0CmV4cHIuZXNjX3JuYVtleHByLmVzY19ybmEgPCAwXSA8LSAwCmV4cHIuZXNjX3JuYSA8LSB0KGV4cHIuZXNjX3JuYSkKcm0oZXNjLmV4cHIsIGVzYy5leHByWiwgZXNjLmtpbnNoaXBfbG9jbywgZXNjLnByb2JzLCBlc2MuZXhwci5Db21CYXQsIGVzYy5yYXcuZXhwciwgY292YXJUaWR5LCBleHByQ29tQmF0LmVzY19ybmEsIGVzYy5jb3ZhciwgZXNjLmNvdmFyVGlkeSkKIyMjIyMgQVRBQyBkYXRhCiMgbG9hZCB0aGUgYXRhYyBwZWFrcwpsb2FkKGhlcmUoIi4uL3BRVExfd2Vic2l0ZS9fZGF0YS9ET19hdGFjc2VxX3ByZWxpbV9EUzA0MjAuUkRhdGEiKSkgIyBjb3VudHMubm9ybQojIHJlbW92ZSBiYWQgc2FtcGxlcwpjb3VudHMubm9ybSA8LSBjb3VudHMubm9ybVssICFjb2xuYW1lcyhjb3VudHMubm9ybSkgJWluJSBjKCJQQjM1Ny4wMSIsICJQQjM1Ny4xNyIpXQpjb3Zhci5lc2NfYXRhYyA8LSBjb3Zhci5tYXRbIXJvd25hbWVzKGNvdmFyLm1hdCkgJWluJSBjKCJQQjM1Ny4wMSIsICJQQjM1Ny4xNyIpLCBdCmNvdmFyVGlkeS5lc2NfYXRhYyA8LSBjb3Zhcl9mdWxsWyFjb3Zhcl9mdWxsJFBCX0lEICVpbiUgYygiUEIzNTcuMDEiLCAiUEIzNTcuMTciKSwgXQpwcm9icy5lc2NfYXRhYyA8LSBwcm9icwojIG5vdGUgdGhhdCB0aGVyZSBhcmUgMiBwbGF0ZXMgb2YgQVRBQyBzYW1wbGVzIHRoYXQgaGF2ZSBiZWVuIHByb2Nlc3NlZC4gSSB3aWxsIHVzZSBjb21CYXQgdG8gcmVtb3ZlIHRoaXMgZWZmZWN0LgpkYXQgPC0gbG9nMXAoKGNvdW50cy5ub3JtKSkKbW9kIDwtIG1vZGVsLm1hdHJpeCh+c2V4LCBkYXRhID0gY292YXJUaWR5LmVzY19hdGFjKQpleHByQ29tQmF0IDwtIHN2YTo6Q29tQmF0KAogIGRhdCA9IGRhdCwgYmF0Y2ggPSBjb3ZhclRpZHkuZXNjX2F0YWMkcGxhdGUsIG1vZCA9IG1vZCwKICBwYXIucHJpb3IgPSBUUlVFLCBwcmlvci5wbG90cyA9IEZBTFNFCikKY291bnRzLm5vcm0yIDwtIGV4cG0xKGV4cHJDb21CYXQpCmNvdW50cy5ub3JtMltjb3VudHMubm9ybTIgPCAwXSA8LSAwCmNvdmFyLmVzY19hdGFjIDwtIGNvdmFyLmVzY19hdGFjWywgInNleCIsIGRyb3AgPSBGQUxTRV0KY291bnRzLm5vcm1aIDwtIGFwcGx5KGNvdW50cy5ub3JtMiwgMSwgcmFua1opCmtpbnNoaXBfbG9jby5lc2NfYXRhYyA8LSBjYWxjX2tpbnNoaXAocHJvYnMuZXNjX2F0YWMsIHR5cGUgPSAibG9jbyIpCnJtKHByb2JzLCBjb3Zhcl9mdWxsLCBjb3Zhci5tYXQsIG1hcF9kYXQsIGRhdCwgbW9kLCBleHByQ29tQmF0LCBjb3VudHMubm9ybSkKIyMjIEFubm90YXRpbmcgdXNpbmcgQ2hpcFNlZWtlciArIFR4RGIuTW11c2N1bHVzLlVDU0MubW0xMC5rbm93bkdlbmUgKHRoaXMgdXNlcyBVQ1NDIGRhdGEgZnJvbSBPY3QsIDIwMTkgd2hpY2ggSSBhc3N1bWUgbWF0Y2hlcyB0byBlbnNlbWJsIHY5OCAoU2VwMTkpKQojIGFubm90YXRlIEF0YWMgZGF0YQojIHByZXAgJiBhbm5vdGF0ZSBkYXRhCmF0YWMuY291bnRzIDwtIGNvdW50cy5ub3JtMiAlPiUKICBhcy5kYXRhLmZyYW1lKCkgJT4lCiAgcm93bmFtZXNfdG9fY29sdW1uKCkgJT4lCiAgc2VwYXJhdGUocm93bmFtZSwgaW50byA9IGMoIkNociIsICJTdGFydCIsICJFbmQiKSwgc2VwID0gIl8iLCByZW1vdmUgPSBGQUxTRSkgJT4lCiAgbXV0YXRlKENociA9IGdzdWIoInBlYWsiLCAiIiwgQ2hyKSkgJT4lCiAgY29sdW1uX3RvX3Jvd25hbWVzKCkKZ3IgPC0gbWFrZUdSYW5nZXNGcm9tRGF0YUZyYW1lKGF0YWMuY291bnRzLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtlZXAuZXh0cmEuY29sdW1ucyA9IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VxbmFtZXMuZmllbGQgPSBjKCJDaHIiKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGFydC5maWVsZCA9ICJTdGFydCIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW5kLmZpZWxkID0gIkVuZCIpCmdyIDwtIGRpZmZsb29wOjphZGRjaHIoZ3IpCnBlYWtBbm5vIDwtIGFubm90YXRlUGVhayhnciwKICBUeERiID0gVHhEYi5NbXVzY3VsdXMuVUNTQy5tbTEwLmtub3duR2VuZSwgYW5ub0RiID0gIm9yZy5NbS5lZy5kYiIsCiAgdHNzUmVnaW9uID0gYygtNTAwMCwgNTAwMCksCiAgbGV2ZWwgPSAidHJhbnNjcmlwdCIsIGFzc2lnbkdlbm9taWNBbm5vdGF0aW9uID0gVFJVRSwKICBnZW5vbWljQW5ub3RhdGlvblByaW9yaXR5ID0gYygiUHJvbW90ZXIiLCAiNVVUUiIsICIzVVRSIiwgIkV4b24iLCAiSW50cm9uIiwgIkRvd25zdHJlYW0iLCAiSW50ZXJnZW5pYyIpLAogIGFkZEZsYW5rR2VuZUluZm8gPSBGQUxTRSwKICBvdmVybGFwID0gIlRTUyIsIHZlcmJvc2UgPSBGQUxTRQopCmF0YWMucGVhay5hbm5vdHNfZnVsbCA8LSBhc190aWJibGUocGVha0Fubm8pICU+JQogIHNlbGVjdCghc3RhcnRzX3dpdGgoIlBCIikpICU+JQogIG11dGF0ZSgKICAgIHNlcW5hbWVzID0gZ3N1YigiY2hyIiwgInBlYWsiLCBzZXFuYW1lcyksCiAgICBjaHIgPSBnc3ViKCJwZWFrIiwgIiIsIHNlcW5hbWVzKQogICkgJT4lCiAgdW5pdGUoInBlYWtfaWQiLCAic2VxbmFtZXMiLCAic3RhcnQiLCAiZW5kIiwgcmVtb3ZlID0gRkFMU0UpICU+JQogIHNlbGVjdCgtc2VxbmFtZXMpCmBgYAoKYGBge3IgaWRfbWF0Y2hpbmcsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGVjaG8gPUZBTFNFfQojIEkgYW0gdXNpbmcgdjk4IGFubm90YXRpb25zIHNpbmNlIHByb3RlaW4gaWQncyBhcmUgdjk4CiMgU2F2ZWQgYWxsIGdlbmUgYW5ub3RhdGlvbnMgZnJvbSBiaW9tYXJ0IHVzaW5nIFNlcHQyMDE5IGFyY2hpdmUgaHR0cDovL3NlcDIwMTkuYXJjaGl2ZS5lbnNlbWJsLm9yZy9iaW9tYXJ0CmFsbF9hbm5vdF92OTggPC0gcmVhZF90c3YoIGhlcmUoIi4uL3BRVExfd2Vic2l0ZS9fZGF0YSIsImVuc2VtYmxfZ2VuZV9hbm5vdGF0aW9uc192OTgudHh0IikpICU+JSAKcmVuYW1lKCAiZW5zZW1ibF9nZW5lX2lkIiA9ICJHZW5lIHN0YWJsZSBJRCIsCiAgICAgICAgICAicHJvdGVpbl9pZCIgPSAiUHJvdGVpbiBzdGFibGUgSUQiLAogICAgICAgICAgImdlbmVfc3RhcnQiID0gIkdlbmUgc3RhcnQgKGJwKSIsCiAgICAgICAgICAiZ2VuZV9lbmQiID0gIkdlbmUgZW5kIChicCkiLAogICAgICAgICAgImdlbmVfY2hyIiA9ICJDaHJvbW9zb21lL3NjYWZmb2xkIG5hbWUiLAogICAgICAgICAgIm1naV9zeW1ib2wiID0gIk1HSSBzeW1ib2wiLAogICAgICAgICAgImdlbmVfYmlvdHlwZSIgPSAiR2VuZSB0eXBlIgogICAgICAgICkgJT4lIAogIGdyb3VwX2J5KGVuc2VtYmxfZ2VuZV9pZCkgJT4lIAogIG11dGF0ZSggbl9nZW5lX2lkID0gbigpKSAlPiUgIyB0aGVyZSBhcmUgY2FzZXMgd2hlcmUgZ2VuZSBpZCBpcyByZXBlYXRlZCB3aXRoIGEgdmFsaWQgcHJvdGVpbiBpZCArIE5BCiAgdW5ncm91cCgpICU+JSAKICBmaWx0ZXIoICEobl9nZW5lX2lkID4xICYgaXMubmEocHJvdGVpbl9pZCkgJiBnZW5lX2Jpb3R5cGUgPT0icHJvdGVpbl9jb2RpbmciKSApICU+JSAKICBzZWxlY3QoLW5fZ2VuZV9pZCkKIyBtYWtlIGFsbC5nZW5lcywgYWxsLnByb3RzLCBhdGFjLnBlYWsuYW5ub3RzCmFsbC5nZW5lcyA8LSBhbGxfYW5ub3Rfdjk4ICU+JSAKICBmaWx0ZXIoIGVuc2VtYmxfZ2VuZV9pZCAlaW4lIGNvbG5hbWVzKGV4cHIuZXNjX3JuYSkpICU+JSAKICBzZWxlY3QoIC1wcm90ZWluX2lkKSAlPiUgCiAgZGlzdGluY3QoKSAKIyBhbGwgZ2VuZXM6CiMgMTQ0MDUvMTQ1NDcgaGFzIGFubm90YXRpb25zIGluIHY5OCwgMTQxIG1pc3NpbmcgYW5ub3RhdGlvbnMKIyBjbG9zZXIgbG9vayBhdCBzb21lIHNob3cgdGhhdCB0aGUgZW5zZW1ibCBnZW5lIGlkcyBoYXZlIGJlZW4gY2hhbmdlZC4gTm90IHN1cmUgd2hhdCB0aGUgYmVzdCB3YXkgaW4gdXBkYXRpbmcgdGhvc2UgYXJlLiAKIyBFeDogRU5TTVVTRzAwMDAwMDI5MzMzIG1hdGNoZXMgUmFzZ2VmMWIgaW4gTUdJIHdoaWNoIGhhcyBFTlNNVVNHMDAwMDAwODk4MDkgYXMgdGhlIG5ldyBlbnNlbWJsIGdlbmUgaWQgaW4gdjk4LiBJIGNhbid0IGZpbmQgdGhlIGNvbm5lY3Rpb24gb3RoZXIgdGhhbiBtYW51YWxseSBzZWFyY2hpbmcgZm9yIGl0ISAKICAKICAKYWxsLnByb3RzIDwtIGFsbF9hbm5vdF92OTggJT4lCiAgZmlsdGVyKCBwcm90ZWluX2lkICVpbiUgY29sbmFtZXMoZXhwci5lc2NfcHJvdCkpICU+JSAKICBmaWx0ZXIoICFpcy5uYShtZ2lfc3ltYm9sKSApICMgSSBhbSByZW1vdmluZyB0aGUgb25lcyB3aXRob3V0IGFuIGFubm90YXRpb24gCiMgNzQzMi83NDMyIGhhcyBhbm5vdGF0aW9ucyEKYWxsX2F0YWNfcGVha19nZW5lX2Fubm90cyA8LSBhbGxfYW5ub3Rfdjk4ICU+JSAgCiAgZmlsdGVyKCBlbnNlbWJsX2dlbmVfaWQgJWluJSBhdGFjLnBlYWsuYW5ub3RzX2Z1bGwkRU5TRU1CTCkgJT4lIAogIHNlbGVjdCggLXByb3RlaW5faWQpICU+JSAKICBkaXN0aW5jdCgpICU+JSAKICBmaWx0ZXIoICFpcy5uYShtZ2lfc3ltYm9sKSB8ICFpcy5uYShlbnNlbWJsX2dlbmVfaWQpKSAjIEkgYW0gcmVtb3ZpbmcgdGhlIG9uZXMgd2l0aG91dCBhbiBhbm5vdGF0aW9uIChuID0gMykKIyByZS13cml0aW5nIHRoZSBhbm5vdGF0aW9ucy4gCmF0YWMucGVhay5hbm5vdHNfZnVsbCA8LSBhdGFjLnBlYWsuYW5ub3RzX2Z1bGwgJT4lIAogIHNlbGVjdChwZWFrX2lkLCAKICAgICAgICAgcGVha19zdGFydCA9IHN0YXJ0LCAKICAgICAgICAgcGVha19lbmQgPSBlbmQsIAogICAgICAgICBwZWFrX3dpZHRoID0gd2lkdGgsIAogICAgICAgICBwZWFrX3N0cmFuZCA9IHN0cmFuZCwgCiAgICAgICAgIGFubm90YXRpb24sIAogICAgICAgICBkaXN0YW5jZVRvVFNTLCAKICAgICAgICAgImVuc2VtYmxfZ2VuZV9pZCI9IkVOU0VNQkwiKSAlPiUgCiAgbGVmdF9qb2luKCBhbGxfYXRhY19wZWFrX2dlbmVfYW5ub3RzKQphdGFjLnBlYWsuYW5ub3RzIDwtIGF0YWMucGVhay5hbm5vdHNfZnVsbCAlPiUgCiAgZmlsdGVyKCAhaXMubmEobWdpX3N5bWJvbCkpCiMgMTAwNDMwLzEwMjE3MyBoYXMgYW5ub3RhdGlvbnMKIyBkZiB3aXRoIGFsbCBlbnNlbWJsIGdlbmUgaWRzIC9wcm90ZWluIGlkcyBmb3VuZCBpbiB0aGUgdGhyZWUgZGF0YSBzZXRzLiAKYWxsX29taWNzX2lkcyA8LSBmdWxsX2pvaW4oIGFsbF9hdGFjX3BlYWtfZ2VuZV9hbm5vdHMsIGFsbC5nZW5lcykgJT4lIAogIGZ1bGxfam9pbiggYWxsLnByb3RzKSAjJT4lIAogICNsZWZ0X2pvaW4oIHNlbGVjdChhdGFjLnBlYWsuYW5ub3RzLCBlbnNlbWJsX2dlbmVfaWQsIHBlYWtfaWQpKSAjIEkgY2FuIGFkZCBwZWFrX2lkcyBpZiBJIHdhbnQgdG8hIAojIHNhdmluZyBmb3IgbGF0ZXIgdXNlCiMgc2F2ZSggYWxsLmdlbmVzLCBhbGwucHJvdHMsIGF0YWMucGVhay5hbm5vdHMsIGZpbGUgPSBoZXJlKCJfZGF0YSIsInVwZGF0ZWRfYW5ub3RhdGlvbnNfMDQwNDIwMjIuUkRhdGEiKSkKYGBgCgpgYGB7ciBsb2FkX3F0bF9kYXRhLCB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCByZXN1bHRzPSJoaWRlIiAsIGVjaG8gPUZBTFNFfQoKIyMjIyMjIyMjIG1lcmdlZCBjYVFUTCwgZVFUTCwgcFFUTAojIHNlZSAiX3NyYy8iIGZvciBkZXRhaWxzIG9uIGhvdyB0aGV5IGFyZSBtZXJnZWQKbG9hZChoZXJlKCIuLi9wUVRMX3dlYnNpdGUvX2RhdGEvcGVha3NfY29tcGFyaXNvbl8xME1iX25vUG9seV92NF93X2F0YWMuUkRhdGEiKSkgIyBwZWFrcy5lc2Mub3ZlcmxhcDIsIHBlYWtzLmVzYy5wcm90LnJuYSwgcGVha3MuZXNjLnJuYS5hdGFjCgojIyMjIyMjIyMgcFFUTCBkYXRhIHdpdGggZWZmZWN0cwpsb2FkKGhlcmUoIi4uL3BRVExfd2Vic2l0ZS9fZGF0YS9ET19tRVNDX3BRVExfZWZmZWN0c19ub1BvbHlfdjIuUkRhdGEiKSkKcGVha3MuZXNjX3Byb3QgPC0gcGVha3MgIyBhbGwgcFFUTCBwZWFrcwplZmZlY3RzX2JsdXAuZXNjX3Byb3QgPC0gZWZmZWN0c19ibHVwICMgYWxsIHBRVEwgZWZmZWN0cyB1c2luZyBibHVwCnJtKHBlYWtzLCBlZmZlY3RzX2JsdXAsIGVmZmVjdHNfc3RkKQojIGFkZGluZyBlZmZlY3RzIHRvIHBRVEwgcGVha3MKcGVha3MuZXNjX3Byb3QuYmx1cCA8LSBjYmluZChwZWFrcy5lc2NfcHJvdCwgZWZmZWN0c19ibHVwLmVzY19wcm90KSAlPiUgCiAgZHBseXI6OnJlbmFtZSgicHJvdGVpbl9pZCIgPSAicGhlbm90eXBlIikKY29sbmFtZXMocGVha3MuZXNjX3Byb3QuYmx1cCkgPC0gYygKICBjb2xuYW1lcyhwZWFrcy5lc2NfcHJvdC5ibHVwKVsxOjJdLAogIHBhc3RlMChjb2xuYW1lcyhwZWFrcy5lc2NfcHJvdC5ibHVwKVszOmRpbShwZWFrcy5lc2NfcHJvdC5ibHVwKVsyXV0sICIuZXNjX3Byb3QiKQopCiMgYWRkaW5nIGFubm90YXRpb25zIHRvIHBRVEwgd2l0aCBlZmZlY3RzCnBlYWtzLmVzY19wcm90LndFZmZzIDwtIHBlYWtzLmVzY19wcm90LmJsdXAgJT4lIAogIGxlZnRfam9pbiggYWxsLnByb3RzKSAlPiUgCiAgbXV0YXRlKG1pZHBvaW50ID0gKGdlbmVfc3RhcnQgKyBnZW5lX2VuZCkgLyAyKSAlPiUgCiAgbXV0YXRlKCBzYW1lX2Nocm9tID0gIChwZWFrX2NociA9PSBnZW5lX2NociksCiAgICAgICAgICBkaWZmID0gYWJzKG1pZHBvaW50IC0gaW50ZXJwX2JwX3BlYWsuZXNjX3Byb3QpKSAlPiUgCiAgbXV0YXRlKCBsb2NhbC5lc2NfcHJvdCA9IGlmZWxzZSggc2FtZV9jaHJvbSAmIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZGlmZiA8IDEwZTA2LCBUUlVFLCBGQUxTRQogICAgKSkgCiMgYWRkaW5nIFJOQSArIHByb3RlaW4gZGV0YWlscyB0byB0aGUgZWZmZWN0cyBkYXRhIGZyYW1lIGZvciBhbGwgZVFUTCAmIHBRVEwgcGVha3MuCnBlYWtzLmVzY19wcm90LmJsdXAgPC0gcGVha3MuZXNjX3Byb3QuYmx1cCAlPiUgCiAgbGVmdF9qb2luKC4sIG11dGF0ZShwZWFrcy5lc2MucHJvdC5ybmEsCiAgICAgICAgICAgICAgICAgICAgICBwZWFrX2NNLmVzY19wcm90ID0gYXMubnVtZXJpYyhwZWFrX2NNLmVzY19wcm90KSwKICAgICAgICAgICAgICAgICAgICAgIHBlYWtfY00uZXNjX3JuYSA9IGFzLm51bWVyaWMocGVha19jTS5lc2Nfcm5hKQopKQojIyMjIyMjIyMgZVFUTCBkYXRhIHdpdGggZWZmZWN0cwpsb2FkKGhlcmUoIi4uL3BRVExfd2Vic2l0ZS9fZGF0YS9FU0NfZVFUTF9lZmZlY3RzLlJEYXRhIikpCnBlYWtzLmVzY19ybmEgPC0gcGVha3MKZWZmZWN0c19ibHVwLmVzY19ybmEgPC0gZWZmZWN0c19ibHVwCmVmZmVjdHNfc3RkLmVzY19ybmEgPC0gZWZmZWN0c19zdGQKcm0ocGVha3MsIGVmZmVjdHNfYmx1cCwgZWZmZWN0c19zdGQpCiMgQWRkaW5nIGVmZmVjdHMgdG8gZVFUTCBwZWFrcwpwZWFrcy5lc2Nfcm5hLmJsdXAgPC0gY2JpbmQocGVha3MuZXNjX3JuYSwgZWZmZWN0c19ibHVwLmVzY19ybmEpICU+JQogIGRwbHlyOjpyZW5hbWUoImVuc2VtYmxfZ2VuZV9pZCIgPSAicGhlbm90eXBlIikKY29sbmFtZXMocGVha3MuZXNjX3JuYS5ibHVwKSA8LSBjKAogIGNvbG5hbWVzKHBlYWtzLmVzY19ybmEuYmx1cClbMToyXSwKICBwYXN0ZTAoY29sbmFtZXMocGVha3MuZXNjX3JuYS5ibHVwKVszOmRpbShwZWFrcy5lc2Nfcm5hLmJsdXApWzJdXSwgIi5lc2Nfcm5hIikKKQojIGFkZGluZyBhbm5vdGF0aW9ucyB0byBlUVRMIHBlYWtzIHdpdGggZWZmZWN0cwpwZWFrcy5lc2Nfcm5hLndFZmZzIDwtIHBlYWtzLmVzY19ybmEuYmx1cCAlPiUgCiAgbGVmdF9qb2luKCBhbGwuZ2VuZXMpICU+JSAKICBtdXRhdGUobWlkcG9pbnQgPSAoZ2VuZV9zdGFydCArIGdlbmVfZW5kKSAvIDIpICU+JSAKICBtdXRhdGUoIHNhbWVfY2hyb20gPSAgKHBlYWtfY2hyID09IGdlbmVfY2hyKSwKICAgICAgICAgIGRpZmYgPSBhYnMobWlkcG9pbnQgLSBpbnRlcnBfYnBfcGVhay5lc2Nfcm5hKSkgJT4lIAogIG11dGF0ZSggbG9jYWwuZXNjX3JuYSA9IGlmZWxzZSggc2FtZV9jaHJvbSAmIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZGlmZiA8IDEwZTA2LCBUUlVFLCBGQUxTRQogICAgKSkKIyBhZGRpbmcgUk5BICsgcHJvdGVpbiBkZXRhaWxzIHRvIHRoZSBlZmZlY3RzIGRhdGEgZnJhbWUgZm9yIGFsbCBlUVRMICYgcFFUTCBwZWFrcy4KcGVha3MuZXNjX3JuYS5ibHVwIDwtIHBlYWtzLmVzY19ybmEuYmx1cCAlPiUgIyAKICBsZWZ0X2pvaW4oLiwgbXV0YXRlKHBlYWtzLmVzYy5wcm90LnJuYSwKICBwZWFrX2NNLmVzY19ybmEgPSBhcy5udW1lcmljKHBlYWtfY00uZXNjX3JuYSksCiAgcGVha19jTS5lc2NfcHJvdCA9IGFzLm51bWVyaWMocGVha19jTS5lc2NfcHJvdCkKKSkKIyMjIyMjIyMjIGNhUVRMIGRhdGEKbG9hZChoZXJlKCIuLi9wUVRMX3dlYnNpdGUvX2RhdGEvYXRhY19lZmZlY3RzX2F0X3F0bF9wZWFrcy5SRGF0YSIpKSAjIHBlYWtzCmF0YWMuZWZmX2JsdXAgPC0gY2JpbmQocGVha3MsIGVmZmVjdHNfYmx1cCkKcGVha3MuZXNjX2F0YWMgPC0gcGVha3MKcm0ocGVha3MsIGVmZmVjdHNfYmx1cCwgZWZmZWN0c19zdGQpCiMgcmVuYW1pbmcgZWZmZWN0cwphdGFjLmVmZl9ibHVwICU+JSAKICBzZWxlY3QoIHBlYWtfaWQgPSBwaGVub3R5cGUsIHBlYWtfY2hyLCBsb2QuZXNjX2F0YWMgPSBsb2QsIGludGVycF9icF9wZWFrLmVzY19hdGFjID0gaW50ZXJwX2JwX3BlYWssCiAgICAgICAgICBBLmVzY19hdGFjID0gQSwgCiAgICAgICAgICBCLmVzY19hdGFjID0gQiwKICAgICAgICAgIEMuZXNjX2F0YWMgPSBDLAogICAgICAgICAgRC5lc2NfYXRhYyA9IEQsIAogICAgICAgICAgRS5lc2NfYXRhYyA9IEUsIAogICAgICAgICAgRi5lc2NfYXRhYyA9IGBGYCwgCiAgICAgICAgICBHLmVzY19hdGFjID0gRywKICAgICAgICAgIEguZXNjX2F0YWMgPSBICiAgICAgICAgICApIC0+IHBlYWtzLmVzY19hdGFjLmJsdXAKIyBhZGQgbG9jYWwgZGlzdGFudCB0byBwZWFrcy5lc2NfYXRhYy5ibHVwCnBlYWtzLmVzY19hdGFjLmJsdXAgJT4lIAogIGxlZnRfam9pbiggLiwgYXRhYy5wZWFrLmFubm90c19mdWxsICU+JSAKICAgICAgICAgICAgICAgICAgICBtdXRhdGUobWlkcG9pbnQgPSAocGVha19zdGFydCtwZWFrX2VuZCkvMiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgYXRhY19jaHIgPSBnc3ViKCJfIiwiIixzdWJzdHIocGVha19pZCw1LDYpKSkgJT4lIAogICAgICAgICAgICAgICAgICAgIHNlbGVjdCggcGVha19pZCwgbWlkcG9pbnQsIGF0YWNfY2hyKQogICAgICAgICAgICAgKSAlPiUgICMgYWRkaW5nIGxvY2F0aW9uIGluZm9ybWF0aW9uIGZvciBlYWNoIHBlYWsKICBtdXRhdGUoIAogICAgbG9jYWwuZXNjX2F0YWMgPSAocGVha19jaHIgPT0gYXRhY19jaHIgJiBhYnMoIG1pZHBvaW50IC0gYXMubnVtZXJpYyhpbnRlcnBfYnBfcGVhay5lc2NfYXRhYykpIDwgMTBlMDYgKSwKICAgICkgLT4gcGVha3MuZXNjX2F0YWMuYmx1cAojIGZpeGluZyBzb21lIHByb2JzIC0tIGZvciBhc3NvY2lhdGlvbiBtYXBwaW5nIAphdHRyaWJ1dGVzKHByb2JzLmVzY19ybmEpJGlzX3hfY2hyIDwtICBhdHRyaWJ1dGVzKHByb2JzLmVzY19hdGFjKSRpc194X2NocgphdHRyaWJ1dGVzKHByb2JzLmVzY19wcm90KSRpc194X2NociA8LSAgYXR0cmlidXRlcyhwcm9icy5lc2NfYXRhYykkaXNfeF9jaHIKIyMjIyBtZXJnZSBlZmZlY3RzCnBlYWtzLm1lcmdlZC5ibHVwIDwtIGZ1bGxfam9pbiggKHBlYWtzLmVzY19ybmEuYmx1cCAlPiUgIHNlbGVjdCgtYnBfZGlmZiwgLXNhbWVfY2hyb20pICksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChwZWFrcy5lc2NfcHJvdC5ibHVwICU+JSBzZWxlY3QoLWJwX2RpZmYsIC1zYW1lX2Nocm9tKSkgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKQpwZWFrcy5lc2Mub3ZlcmxhcC53RWZmcyA8LSBwZWFrcy5lc2Mub3ZlcmxhcDIgJT4lIAogIG11dGF0ZSggCiAgICBwZWFrX2NNLmVzY19ybmEgPSBhcy5udW1lcmljKHBlYWtfY00uZXNjX3JuYSksCiAgICBwZWFrX2NNLmVzY19wcm90ID0gYXMubnVtZXJpYyhwZWFrX2NNLmVzY19wcm90KSwKICAgIGJlZm9yZS5lc2NfYXRhYyA9IGJlZm9yZSwgCiAgICBhZnRlci5lc2NfYXRhYyA9IGFmdGVyCiAgICApICU+JSAKICBsZWZ0X2pvaW4oIHBlYWtzLmVzY19hdGFjLmJsdXAgJT4lICBzZWxlY3QoLW1pZHBvaW50KSkgJT4lIAogIGxlZnRfam9pbiggKHBlYWtzLmVzY19ybmEud0VmZnMgJT4lICBzZWxlY3QoIGVuc2VtYmxfZ2VuZV9pZCwgcGVha19jaHIsIGxvZC5lc2Nfcm5hICwgYmVmb3JlLmVzY19ybmEsIGFmdGVyLmVzY19ybmEsIHBhc3RlMChMRVRURVJTWzE6OF0sIi5lc2Nfcm5hIikpKSApICU+JSAKICBsZWZ0X2pvaW4oIChwZWFrcy5lc2NfcHJvdC53RWZmcyAlPiUgc2VsZWN0KCBwcm90ZWluX2lkLCBwZWFrX2NociwgbG9kLmVzY19wcm90ICwgYmVmb3JlLmVzY19wcm90LCBhZnRlci5lc2NfcHJvdCwgcGFzdGUwKExFVFRFUlNbMTo4XSwiLmVzY19wcm90IikpKSApCmBgYAoKYGBge3Igc2hhcmVkX2RhdGEsIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIGVjaG8gPUZBTFNFfQojIyMjIFNoYXJlZCBkYXRhCiMgZ2V0IHRoZSBzZXQgb2Ygc2hhcmVkIGdlbmVzIGJ0dyBwcm90ZWluICsgcm5hCnNoYXJlZC5nZW5lcyA8LSBpbm5lcl9qb2luKCBhbGwuZ2VuZXMsIGFsbC5wcm90cykKIyBzaGFyZWQgaW4gYWxsIHRocmVlIGRhdGEgc2V0cwp0aHJlZXdheS5zaGFyZWQuZ2VuZXMgPC0gYXRhYy5wZWFrLmFubm90cyAlPiUgCiAgZmlsdGVyKCBlbnNlbWJsX2dlbmVfaWQgJWluJSBzaGFyZWQuZ2VuZXMkZW5zZW1ibF9nZW5lX2lkKSAlPiUgICMgZ2V0IGdlbmVzIGZvdW5kIGluIGFsbCB0aHJlZSBvbWljcwogIGxlZnRfam9pbiggYWxsLnByb3RzKSAlPiUgCiAgZ3JvdXBfYnkoZW5zZW1ibF9nZW5lX2lkKSAlPiUKICBtdXRhdGUobmV3X3N5bWJvbD1wYXN0ZTAobWdpX3N5bWJvbCwiXyIsMTpuKCkpLCBuZXdfZ2VuZV9pZD1wYXN0ZTAoZW5zZW1ibF9nZW5lX2lkLCJfIiwxOm4oKSkpICU+JSAKICB1bmdyb3VwKCkKIyBnZXQgdGhlIHNldCBvZiBzaGFyZWQgc2FtcGxlcwpzaGFyZWQuc2FtcGxlcyA8LSBpbnRlcnNlY3QoCiAgcm93bmFtZXMoZXhwci5lc2Nfcm5hKVshZ3JlcGwoInJlcEIiLCByb3duYW1lcyhleHByLmVzY19ybmEpKV0sCiAgcm93bmFtZXMoZXhwci5lc2NfcHJvdClbIWdyZXBsKCJyZXBCIiwgcm93bmFtZXMoZXhwci5lc2NfcHJvdCkpXQopCnNoYXJlZC5wcm9icy5lc2NfcHJvdCA8LSBwcm9icy5lc2NfcHJvdFtpbmQgPSBzaGFyZWQuc2FtcGxlc10Kc2hhcmVkLnByb2JzLmVzY19ybmEgPC0gcHJvYnMuZXNjX3JuYVtpbmQgPSBzaGFyZWQuc2FtcGxlc10KIyBsb2FkIHNhbXBsZSBtYXRjaGluZyB0YWJsZSBmb3IgYXRhYwojIGxvYWQgbWF0Y2hpbmcgc2FtcGxlIG5hbWVzIGZvciBhdGFjLXNlcSBkYXRhCmFsbC5pZHMgPC0gcmVhZF90c3YoaGVyZSgiLi4vcFFUTF93ZWJzaXRlL19kYXRhL0NvcnJlY3RlZF9QQklEX1NhbXBsZU1hdGNoX0tleV92NC50c3YiKSkgJT4lCiAgbXV0YXRlKHNhbXBsZWlkLmVzY19wcm90ID0gZ3N1YigicmVwMSIsICJyZXBBIiwgc2FtcGxlaWQuZXNjX3Byb3QpKQpjb3JyZWN0LmF0YWMuaWRzIDwtIHJlYWRfdHN2KGhlcmUoIi4uL3BRVExfd2Vic2l0ZS9fZGF0YS9BVEFDX3NhbXBsZWlkc19jb3JyZWN0ZWQudHN2IikpCnNhbXBsZS5tYXRjaGVzIDwtIGNvcnJlY3QuYXRhYy5pZHMgJT4lCiAgbXV0YXRlKHNhbXBsZWlkID0gaWZlbHNlKGVuZHNXaXRoKGNvcnJlY3RfaWQsICJCIiksIHBhc3RlMChjb3JyZWN0X2lkLCAiX3JlcEIiKSwgcGFzdGUwKGNvcnJlY3RfaWQsICJfcmVwQSIpKSkgJT4lCiAgbXV0YXRlKHNhbXBsZWlkID0gaWZlbHNlKGVuZHNXaXRoKGNvcnJlY3RfaWQsICJDIiksIHBhc3RlMChjb3JyZWN0X2lkLCAiX3JlcEMiKSwgc2FtcGxlaWQpKSAlPiUKICBmdWxsX2pvaW4oLiwgdGliYmxlKHJuYV9pZCA9IHJvd25hbWVzKGV4cHIuZXNjX3JuYSkpLCBieSA9IGMoInNhbXBsZWlkIiA9ICJybmFfaWQiKSkgJT4lCiAgZnVsbF9qb2luKC4sIHRpYmJsZShwcm90X2lkID0gcm93bmFtZXMoZXhwci5lc2NfcHJvdCkpLCBieSA9IGMoInNhbXBsZWlkIiA9ICJwcm90X2lkIikpCnNhbXBsZS5tYXRjaGVzLm5vZHVwcyA8LSBmaWx0ZXIoc2FtcGxlLm1hdGNoZXMsICFlbmRzV2l0aChzYW1wbGVpZCwgIkIiKSwgIWVuZHNXaXRoKHNhbXBsZWlkLCAiQyIpKQojIHRoZXJlIGFyZSBzb21lIHJuYS9wcm90ZWluIHNhbXBsZXMgdGhhdCBhcmUgbm90IGZvdW5kIGluIHRoZSBhdGFjIGRhdGEKIyBJIGFtIGFkZGluZyB0aGUgdG9wX211Z2EgaWRzIGZvciB0aG9zZQptaXNzaW5nLnNhbXBsZXMgPC0gZmlsdGVyKAogIGFsbC5pZHMsCiAgKHNhbXBsZWlkLmVzY19ybmEgJWluJSBmaWx0ZXIoc2FtcGxlLm1hdGNoZXMubm9kdXBzLCBpcy5uYSh0b3BfbXVnYSkpJHNhbXBsZWlkICYgbWl4dXAuZXNjX3JuYSA9PSBGQUxTRSkgfAogICAgKHNhbXBsZWlkLmVzY19wcm90ICVpbiUgZmlsdGVyKHNhbXBsZS5tYXRjaGVzLm5vZHVwcywgaXMubmEodG9wX211Z2EpKSRzYW1wbGVpZCAmIG1peHVwLmVzY19wcm90ID09IEZBTFNFKQopICU+JQogIHNlbGVjdCh0b3BfbXVnYSwgc2FtcGxlaWQuZXNjX3JuYSwgc2FtcGxlaWQuZXNjX3Byb3QsIFBCSUQpICU+JQogIG11dGF0ZShzYW1wbGVpZCA9IGlmZWxzZShpcy5uYShzYW1wbGVpZC5lc2Nfcm5hKSwgc2FtcGxlaWQuZXNjX3Byb3QsIHNhbXBsZWlkLmVzY19ybmEpKSAlPiUKICBzZWxlY3QoLXNhbXBsZWlkLmVzY19ybmEsIC1zYW1wbGVpZC5lc2NfcHJvdCkgJT4lCiAgZGlzdGluY3QoKQpzYW1wbGUubWF0Y2hlcy5hbGwgPC0gc2FtcGxlLm1hdGNoZXMubm9kdXBzICU+JQogIGZ1bGxfam9pbiguLCBtaXNzaW5nLnNhbXBsZXMsIGJ5ID0gYygic2FtcGxlaWQiKSkgJT4lCiAgbXV0YXRlKAogICAgdG9wX211Z2EgPSBpZmVsc2UoIWlzLm5hKHRvcF9tdWdhLngpLCB0b3BfbXVnYS54LCB0b3BfbXVnYS55KSwKICAgIFBCSUQgPSBpZmVsc2UoIWlzLm5hKFBCSUQueCksIFBCSUQueCwgUEJJRC55KQogICkgJT4lCiAgc2VsZWN0KHNhbXBsZWlkLCBjb3JyZWN0X2lkLCBBVEFDLCB0b3BfbXVnYSwgUEJJRCkgJT4lCiAgZmlsdGVyKCFpcy5uYSh0b3BfbXVnYSkpICMgcmVtb3ZlIHRoZSBvbmVzIHRoYXQgYXJlIHN0aWxsIE5BICsgIGFkZCB0aGVtIGJhY2sgYmVsb3cKIyB0aGVyZSBhcmUgc3RpbGwgMiBzYW1wbGVzIHRoYXQgYXJlIG1pc21hdGNoZXMgd2l0aCBtaXNzaW5nIHRvcF9tdWdhIGlkcwojIFBCMzU5LjMzX3JlcEEgYW5kIFBCMzYxLjcyX3JlcEEsIEkgYW0gY2hhbmdpbmcgdGhvc2UgbWFudWFsbHkgdXNpbmcgYWxsLmlkcwptaXh1cC5zYW1wbGVzIDwtIHRpYmJsZSgKICBzYW1wbGVpZCA9IGMoIlBCMzU5LjMzX3JlcEEiLCAiUEIzNjEuNzJfcmVwQSIpLAogIHRvcF9tdWdhID0gYygiQTkwM0RJMUIuQzAzIiwgIkE5MDNESTEyLkUwOSIpLAogIFBCSUQgPSBjKCJQQjM1OS4zMyIsICJQQjM2MS43MiIpLAogIEFUQUMgPSBjKE5BLCBOQSksIGNvcnJlY3RfaWQgPSBjKE5BLCBOQSkKKQpzYW1wbGUubWF0Y2hlcy5hbGwgPC0gc2FtcGxlLm1hdGNoZXMuYWxsICU+JQogIHJiaW5kKC4sIG1peHVwLnNhbXBsZXMpCiMgRm9yIG1hcHBpbmcgbGF0ZXIKIyBJIGhhdmUgZmFjdG9ycyBmb3IgYWxsIDIwMCBsaW5lcyArIGNhbiBtYXAgd2l0aCBhbGwKIyBJIG5lZWQgdG8gZ2V0IHRoZSBnZW5vcHJvYnMgZm9yIGFsbCEKIyBsb2FkIGFsbCAzIGFuZCBzdWJzZXQgKyBtZXJnZQphdGFjLnNhbXBsZXMgPC0gc2FtcGxlLm1hdGNoZXMuYWxsICU+JSAKICBmaWx0ZXIoQVRBQyAlaW4lIGNvbG5hbWVzKGNvdW50cy5ub3JtMikpCm90aGVyLnNhbXBsZXMgPC0gc2FtcGxlLm1hdGNoZXMuYWxsICU+JSBmaWx0ZXIoCiAgc2FtcGxlaWQgJWluJSByb3duYW1lcyhleHByLmVzY19ybmEpIHwKICAgIHNhbXBsZWlkICVpbiUgcm93bmFtZXMoZXhwci5lc2NfcHJvdCksCiAgIUFUQUMgJWluJSBjb2xuYW1lcyhjb3VudHMubm9ybTIpCikKc2FtcGxlLm1hdGNoZXMucm5hIDwtIHNhbXBsZS5tYXRjaGVzLmFsbCAlPiUKICBmaWx0ZXIoc2FtcGxlaWQgJWluJSByb3duYW1lcyhleHByLmVzY19ybmEpLCAhaXMubmEoQVRBQykpCnNhbXBsZS5tYXRjaGVzLnByb3QgPC0gc2FtcGxlLm1hdGNoZXMuYWxsICU+JQogIGZpbHRlcihzYW1wbGVpZCAlaW4lIHJvd25hbWVzKGV4cHIuZXNjX3Byb3QpLCAhaXMubmEoQVRBQykpCiMgU2hhcmluZyBhbmQgc2V0dGluZyBuYW1lcwpzdWIucHJvYnMuZXNjX3Byb3QgPC0gcHJvYnMuZXNjX3Byb3RbaW5kID0gb3RoZXIuc2FtcGxlcyRzYW1wbGVpZF0KbmV3LmlkcyA8LSBvdGhlci5zYW1wbGVzJHRvcF9tdWdhCm5hbWVzKG5ldy5pZHMpIDwtIG90aGVyLnNhbXBsZXMkc2FtcGxlaWQKc3ViLnByb2JzLmVzY19wcm90IDwtIHJlcGxhY2VfaWRzKHN1Yi5wcm9icy5lc2NfcHJvdCwgaWRzID0gbmV3LmlkcykKc3ViLnByb2JzLmVzY19hdGFjIDwtIHByb2JzLmVzY19hdGFjW2luZCA9IGF0YWMuc2FtcGxlcyRBVEFDXQpuZXcuaWRzMiA8LSBhdGFjLnNhbXBsZXMkdG9wX211Z2EKbmFtZXMobmV3LmlkczIpIDwtIGF0YWMuc2FtcGxlcyRBVEFDCnN1Yi5wcm9icy5lc2NfYXRhYyA8LSByZXBsYWNlX2lkcyhzdWIucHJvYnMuZXNjX2F0YWMsIGlkcyA9IG5ldy5pZHMyKQphdHRyaWJ1dGVzKHN1Yi5wcm9icy5lc2NfYXRhYykkY3Jvc3N0eXBlIDwtICJETyIKYXR0cmlidXRlcyhzdWIucHJvYnMuZXNjX2F0YWMpJGlzX3hfY2hyIDwtIGF0dHJpYnV0ZXMoc3ViLnByb2JzLmVzY19wcm90KSRpc194X2NocgptZXJnZWQucHJvYnMgPC0gcmJpbmQoc3ViLnByb2JzLmVzY19hdGFjLCBzdWIucHJvYnMuZXNjX3Byb3QpCmtpbnNoaXAgPC0gY2FsY19raW5zaGlwKG1lcmdlZC5wcm9icywgdHlwZSA9ICJsb2NvIikKb3RoZXIuY292YXIgPC0gY292YXIuZXNjX3Byb3QgJT4lCiAgYXMuZGF0YS5mcmFtZSgpICU+JQogIHJvd25hbWVzX3RvX2NvbHVtbigpICU+JQogIGZpbHRlcihyb3duYW1lICVpbiUgb3RoZXIuc2FtcGxlcyRzYW1wbGVpZCkgJT4lCiAgbGVmdF9qb2luKG90aGVyLnNhbXBsZXMsIGJ5ID0gYygicm93bmFtZSIgPSAic2FtcGxlaWQiKSkgJT4lCiAgY29sdW1uX3RvX3Jvd25hbWVzKCJ0b3BfbXVnYSIpICU+JQogIHNlbGVjdChzZXgpICU+JQogIGFzLm1hdHJpeCgpCmF0YWMuY292YXIgPC0gY292YXJUaWR5LmVzY19hdGFjW2NvdmFyVGlkeS5lc2NfYXRhYyRQQl9JRCAlaW4lIGF0YWMuc2FtcGxlcyRBVEFDLCBjKCJQQl9JRCIsICJzZXgiKV0gJT4lCiAgbGVmdF9qb2luKGF0YWMuc2FtcGxlcywgYnkgPSBjKCJQQl9JRCIgPSAiQVRBQyIpKSAlPiUKICBtdXRhdGUoc2V4ID0gaWZlbHNlKHNleCA9PSAiRiIsIDAsIDEpKSAlPiUKICBjb2x1bW5fdG9fcm93bmFtZXMoInRvcF9tdWdhIikgJT4lCiAgc2VsZWN0KHNleCkgJT4lCiAgYXMubWF0cml4KCkKbWVyZ2VkLmNvdmFyIDwtIHJiaW5kKGF0YWMuY292YXIsIG90aGVyLmNvdmFyKQp0aHJlZXdheS5zaGFyZWQuc2FtcGxlcyA8LSBmaWx0ZXIoc2FtcGxlLm1hdGNoZXMsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2FtcGxlaWQgJWluJSBzaGFyZWQuc2FtcGxlcywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBVEFDICVpbiUgY29sbmFtZXMoYXRhYy5jb3VudHMpKSAlPiUKICBsZWZ0X2pvaW4oLiwgc2FtcGxlLm1hdGNoZXMuYWxsKQp0aHJlZXdheS5zaGFyZWQucHJvYnMgPC0gbWVyZ2VkLnByb2JzW2luZCA9IHRocmVld2F5LnNoYXJlZC5zYW1wbGVzJHRvcF9tdWdhXQpzaGFyZWQuYXRhYy5kYXRhIDwtIHQoY291bnRzLm5vcm0yW3RocmVld2F5LnNoYXJlZC5nZW5lcyRwZWFrX2lkLCB0aHJlZXdheS5zaGFyZWQuc2FtcGxlcyRBVEFDXSkKY29sbmFtZXMoc2hhcmVkLmF0YWMuZGF0YSkgPC0gdGhyZWV3YXkuc2hhcmVkLmdlbmVzJG5ld19zeW1ib2wKcm93bmFtZXMoc2hhcmVkLmF0YWMuZGF0YSkgPC0gdGhyZWV3YXkuc2hhcmVkLnNhbXBsZXMkc2FtcGxlaWQKc2hhcmVkLnJuYS5kYXRhIDwtIChleHByLmVzY19ybmFbdGhyZWV3YXkuc2hhcmVkLnNhbXBsZXMkc2FtcGxlaWQsIHRocmVld2F5LnNoYXJlZC5nZW5lcyRlbnNlbWJsX2dlbmVfaWRdKQpjb2xuYW1lcyhzaGFyZWQucm5hLmRhdGEpIDwtIHRocmVld2F5LnNoYXJlZC5nZW5lcyRuZXdfc3ltYm9sCnNoYXJlZC5wcm90LmRhdGEgPC0gKGV4cHIuZXNjX3Byb3RbdGhyZWV3YXkuc2hhcmVkLnNhbXBsZXMkc2FtcGxlaWQsIHRocmVld2F5LnNoYXJlZC5nZW5lcyRwcm90ZWluX2lkXSkKY29sbmFtZXMoc2hhcmVkLnByb3QuZGF0YSkgPC0gdGhyZWV3YXkuc2hhcmVkLmdlbmVzJG5ld19zeW1ib2wKIyBnZXQgc2hhcmVkIHF0bCBwZWFrcwpwZWFrcy5zaGFyZWQuZ2VuZXMgPC0gcGVha3MuZXNjLm92ZXJsYXAyICU+JQogIGZpbHRlcihlbnNlbWJsX2dlbmVfaWQgJWluJSBzaGFyZWQuZ2VuZXMkZW5zZW1ibF9nZW5lX2lkIHwKICAgcHJvdGVpbl9pZCAlaW4lIHNoYXJlZC5nZW5lcyRwcm90ZWluX2lkKSAlPiUKICBtdXRhdGUoCiAgICBsb2QuZXNjX3JuYSA9IGlmZWxzZShpcy5uYShsb2QuZXNjX3JuYSksIDAsIGxvZC5lc2Nfcm5hKSwKICAgIGxvZC5lc2NfcHJvdCA9IGlmZWxzZShpcy5uYShsb2QuZXNjX3Byb3QpLCAwLCBsb2QuZXNjX3Byb3QpCiAgKSAlPiUKICBtdXRhdGUocGVha19jTS5lc2NfcHJvdCA9IGFzLm51bWVyaWMocGVha19jTS5lc2NfcHJvdCksIAogICAgICAgICBwZWFrX2NNLmVzY19ybmEgPSBhcy5udW1lcmljKHBlYWtfY00uZXNjX3JuYSkpCmBgYAoKYGBge3IgbG9hZF9nZW5lX3NldHMsIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHJlc3VsdHM9J2hpZGUnLCBlY2hvID1GQUxTRX0KIyBDb21wbGV4IG1lbWJlcnMgcmV0cmVpZXZlZCBmcm9tIE9yaSBldCBhbCAyMDE2LCBhZGRpdGlvbmFsIGZpbGUyOiAgaHR0cHM6Ly92YXJpYWJsZWNvbXBsZXhlcy5lbWJsLmRlL2h0bWwtdGFibGVzL0FkZGl0aW9uYWxfZmlsZV8yLmh0bWwKY29tcGxleGVzIDwtIHJlYWRfeGxzeChwYXRoID0gaGVyZSgiLi4vcFFUTF93ZWJzaXRlL19kYXRhIiwgInByb3RlaW5fY29tcGxleGVzLnhsc3giKSkgIyBBc3N1bWluZyB0aGV5IGFyZSB1c2luZyAyMDE2IGh1bWFuIGVuc2VtYmwgaWQncy4gYnV0IG5vdCB3b3JyeWluZyBhYm91dCBpdCBhdG0uCmNvbXBsZXguZ2VuZXMgPC0gKHN0cl9zcGxpdChjb21wbGV4ZXMkYE1lbWJlciBpZGVudGlmaWVycyAoaHVtYW4gRW5zZW1ibCBnZW5lKWAsICIgIikpCm5hbWVzKGNvbXBsZXguZ2VuZXMpIDwtIGNvbXBsZXhlcyRgQ29tcGxleCBOYW1lYAojICMgcnVubmluZyB0aGUgY29kZSBiZWxvdyBhbmQgc2F2aW5nIHRvIFJEYXRhIGZpbGUgdG8gcmUtdXNlCiMgbGlicmFyeShiaW9tYVJ0KQojIG1hcnRfaHVtYW4gPC0gdXNlTWFydCgiZW5zZW1ibCIsIGRhdGFzZXQgPSAiaHNhcGllbnNfZ2VuZV9lbnNlbWJsIiwgaG9zdCA9ICJodHRwOi8vc2VwMjAxOS5hcmNoaXZlLmVuc2VtYmwub3JnIikKIyBtYXJ0X21vdXNlIDwtIHVzZU1hcnQoImVuc2VtYmwiLCBkYXRhc2V0ID0gIm1tdXNjdWx1c19nZW5lX2Vuc2VtYmwiLCBob3N0ID0gImh0dHA6Ly9zZXAyMDE5LmFyY2hpdmUuZW5zZW1ibC5vcmciKQojIG1hdGNoZWQuaWRzIDwtIGdldExEUygKIyAgIGF0dHJpYnV0ZXMgPSBjKCJlbnNlbWJsX2dlbmVfaWQiKSwKIyAgIGZpbHRlcnMgPSAiZW5zZW1ibF9nZW5lX2lkIiwKIyAgIHZhbHVlcyA9IHVuaXF1ZSh1bmxpc3QoY29tcGxleC5nZW5lcykpLAojICAgbWFydCA9IG1hcnRfaHVtYW4sCiMgICBhdHRyaWJ1dGVzTCA9IGMoImVuc2VtYmxfZ2VuZV9pZCIpLAojICAgbWFydEwgPSBtYXJ0X21vdXNlCiMgKQojIGNvbXBsZXguZ2VuZS5saXN0IDwtIG1hdGNoZWQuaWRzICU+JQojICAgcmVuYW1lKCBodW1hbl9pZHMgPSBgR2VuZS5zdGFibGUuSURgLAojICAgICAgICAgICBlbnNlbWJsX2dlbmVfaWQgPSBgR2VuZS5zdGFibGUuSUQuMWApICU+JQojICAgbGVmdF9qb2luKAojICAgICBmdWxsX2pvaW4oIGFsbC5nZW5lcywgYWxsLnByb3RzKQojICAgICApICU+JSAgIyBhZGRpbmcgYWxsIGFubm90YXRpb25zCiMgICBmaWx0ZXIoIGVuc2VtYmxfZ2VuZV9pZCAlaW4lIGFsbC5nZW5lcyRlbnNlbWJsX2dlbmVfaWQgfAojICAgICAgICAgICAgIHByb3RlaW5faWQgJWluJSBhbGwucHJvdHMkcHJvdGVpbl9pZCkgIyBmaWx0ZXJpbmcgZm9yIHRoZSBnZW5lcyArIHByb3RlaW5zIGluIG91ciBkYXRhc2V0CiMgIyBub3RlIHRoYXQgMjAgaHVtYW4gaWRzIGRvbid0IGhhdmUgMS0xIG1hcHBpbmcsIHRoZXkgbWF0Y2ggMTAgZ2VuZXMuIE1haW5seSBiZWNhdXNlIHRoYXQgY29tcGxleCBzdWJ1bml0IGlzIG5vdCBmb3VuZCBpbiBtaWNlLgojICMgY29tcGxleC5nZW5lLmxpc3QgJT4lICBncm91cF9ieShlbnNlbWJsX2dlbmVfaWQsIHByb3RlaW5faWQpICU+JSAgbXV0YXRlKCBuID1uKCkpICU+JSBmaWx0ZXIoIG4+MSkgJT4lIHZpZXcoKQojIAojIHNhdmUoY29tcGxleC5nZW5lLmxpc3QsIGZpbGUgPSBoZXJlKCJfZGF0YSIsImNvbXBsZXhfZ2VuZV9saXN0LlJEYXRhIikpCmxvYWQoaGVyZSgiLi4vcFFUTF93ZWJzaXRlL19kYXRhL2NvbXBsZXhfZ2VuZV9saXN0LlJEYXRhIikpCiMgZ2V0dGluZyBURiBsaXN0CmFsbC50ZnMgPC0gcmVhZHhsOjpyZWFkX3hsc3gocGF0aCA9IGhlcmUoIi4uL3BRVExfd2Vic2l0ZS9fZGF0YS9Nb3VzZV9URnNfVGNvRkRCLnhsc3giKSkgJT4lCiAgc2VsZWN0KFN5bWJvbCkgJT4lCiAgcmVuYW1lKG1naV9zeW1ib2wgPSBTeW1ib2wpCgogIAojIGVzYyBnZW5lIGxpc3RzCiMgbG9hZCBsaXN0cwojIGdldCBnZW5lIGxpc3RzIGZvciBoZWF0bWFwcwojIEZyb20gWHUgZXQgYWwgMjAxNCBwYXBlcgojIEkgZmVkIHRoZSBsaXN0IHRvIE1HSSBhbmQgb25seSBUY2YzIGhhcyBhbiBvbGQgc3ltYm9sIFRjZjdsMQp4dS5nZW5lcyA8LSByZWFkX3hsc3goaGVyZSgiLi4vcFFUTF93ZWJzaXRlL19kYXRhL0dlbmVMaXN0LUVTY2VsbC1QbHVNYWludC54bHN4IiksIHNoZWV0ID0gMSkgJT4lCiAgIG11dGF0ZSggR2VuZSA9IGlmZWxzZSggR2VuZSA9PSJUY2YzIiwgIlRjZjdsMSIsR2VuZSkpICU+JSAjIHVwZGF0aW5nIHNvbWUgbmFtZXMgdG8gbWF0Y2ggb3VyIG1naV9zeW1ib2xzCiAgbGVmdF9qb2luKC4sIGFsbF9vbWljc19pZHMsIGJ5ID0gYygiR2VuZSIgPSAibWdpX3N5bWJvbCIpKSAjIExhYmVsID0gInBsdXJpcG90ZW5jeSIsICJtZXNvZGVybSIgLi4uZXRjLgojIEZyb20gS2Fsa2FuIGV0IGFsIDIwMTcgcGFwZXIKIyBJIGZlZCB0aGUgbGlzdCB0byBNR0kgYW5kIG9ubHkgVGNmMyBoYXMgYW4gb2xkIHN5bWJvbCBUY2Y3bDEKa2Fsay5nZW5lcyA8LSByZWFkX3hsc3goaGVyZSgiLi4vcFFUTF93ZWJzaXRlL19kYXRhL0dlbmVMaXN0LUVTY2VsbC1LYWxrYW4yMDE3Lnhsc3giKSwgc2hlZXQgPSAxKSAlPiUKICBtdXRhdGUoIEdlbmUgPSBpZmVsc2UoIEdlbmUgPT0iVGNmMyIsICJUY2Y3bDEiLEdlbmUpKSAlPiUgIyB1cGRhdGluZyBzb21lIG5hbWVzIHRvIG1hdGNoIG91ciBtZ2lfc3ltYm9scwogIGxlZnRfam9pbiguLCBhbGxfb21pY3NfaWRzLCBieSA9IGMoIkdlbmUiID0gIm1naV9zeW1ib2wiKSkgIyBMYWJlbCA9ICIgbmFpdmVfcGx1cmlwb3RlbmN5IiAuLi4gZXRjLgojIFRoZXNlIGFyZSA6UG90ZW50aWFsIHBsdXJpcG90ZW5jeSBhc3NvY2lhdGVkIGdlbmVzIGZyb20gbXVsdGlwbGUgZ2Vub21lLXdpZGUgUk5BaSBzY3JlZW5zIHN0dWRpZXMuCiMgZG93bmxvYWRlZCBmcm9tOiBodHRwOi8vd3d3Lm1hYXlhbmxhYi5uZXQvRVNDQVBFL2Rvd25sb2FkL1JOQWloaXRzLnR4dC56aXAKIyBJIGZlZCB0aGUgbGlzdCB0byBNR0kgYW5kIG1hbnkgZ2VuZXMgaGF2ZSBhbiBvbGQgc3ltYm9sLCBJIGFkZGVkIHRob3NlIHRvIHRoZSBmaWxlIGFzIHdlbGwgLSBSTkFoaXRzX3VwZGF0ZWQueGxzeAojIEhlcmUgbWVyZ2luZyB0aGF0IHRvIHRoZSBvbGQgbGlzdCB0byBpbmNsdWRlIGJvdGggb2xkICsgbmV3IHN5bWJvbHMgaW4gY2FzZSB3ZSBoYXZlIHRoZSBvbGRlciBvbmVzIGluIG91ciBhbm5vdGF0aW9ucwplc2NhcGUuZ2VuZXMgPC0gcmVhZF90c3YoaGVyZSgiLi4vcFFUTF93ZWJzaXRlL19kYXRhL1JOQWloaXRzLnR4dCIpKSAlPiUgIyB0aGVzZSBoYXZlIGNhcGl0YWwgbGV0dGVyIGdlbmUgbmFtZXMKICBzZWxlY3QoZ2VuZU5hbWUpICU+JQogIHJiaW5kKCByZWFkX3hsc3goaGVyZSgiLi4vcFFUTF93ZWJzaXRlL19kYXRhL1JOQWloaXRzX3VwZGF0ZWQueGxzeCIpLCBzaGVldCA9IDEpICU+JSAKICAgICAgICAgICBzZWxlY3QoZ2VuZU5hbWUgPSBTeW1ib2wpICU+JSAKICAgICAgICAgICBmaWx0ZXIoIWlzLm5hKGdlbmVOYW1lKSkKICApICU+JSAKICBkaXN0aW5jdCgpICU+JSAKICBtdXRhdGUobWdpX3N5bWJvbCA9IHBhc3RlMCgoc3Vic3RyaW5nKGdlbmVOYW1lLCAxLCAxKSksIHRvbG93ZXIoc3Vic3RyaW5nKGdlbmVOYW1lLCAyKSkpKSAlPiUKICBzZWxlY3QoLWdlbmVOYW1lKSAlPiUKICBsZWZ0X2pvaW4oIGFsbF9vbWljc19pZHMpIAojIFRoZXNlIGFyZTogTGlzdHMgb2YgRVNDIGFuZCBkaWZmZmVyZW50aWF0aW5nIEVTQy1zcGVjaWZpYyBwcm90ZWlucy4gV2UgY29sbGVjdGVkIDE5LDgwMSBFU0MgYW5kIGRpZmZmZXJlbnRpYXRpbmcgRVNDLXNwZWNpZmljIHByb3RlaW5zIGZyb20gcHJvdGVvbWljcy4gCiMgZG93bmxvYWRlZCBmcm9tOiBodHRwOi8vd3d3Lm1hYXlhbmxhYi5uZXQvRVNDQVBFL2Rvd25sb2FkL3Byb3Rlb21pY3NFU0MudHh0LnppcAojIHVybCA8LSAiaHR0cDovL3d3dy5tYWF5YW5sYWIubmV0L0VTQ0FQRS9kb3dubG9hZC9wcm90ZW9taWNzRVNDLnR4dC56aXAiCiMgZG93bmxvYWQuZmlsZSh1cmwsIGhlcmUoIl9kYXRhL3Byb3Rlb21pY3NFU0MudHh0LnppcCIpKQojIHppcDo6dW56aXAoaGVyZSgiX2RhdGEvcHJvdGVvbWljc0VTQy50eHQuemlwIiksIG92ZXJ3cml0ZSA9IEYsIGV4ZGlyID0gIl9kYXRhLyIpCiMgSSB1cGxvYWRlZCB0aGUgbW91c2Ugc3Vic2V0cyB0byBiaW1hcnQgKyBjb252ZXJ0ZWQgdGhlbSBtYW51YWxseQplc2NhcGVfZGlmZl9nZW5lcyA8LSByZWFkX3RzdiggIi4uL3BRVExfd2Vic2l0ZS9fZGF0YS9lc2NhcGVfZGlmZl9nZW5lcy50c3YiKSAlPiUgCiAgcmVuYW1lKCBlbnNlbWJsX2dlbmVfaWQgPSBgR2VuZSBzdGFibGUgSURgLCBtZ2lfc3ltYm9sID0gYE1HSSBzeW1ib2xgLGdlbmVJRCA9IGBOQ0JJIGdlbmUgKGZvcm1lcmx5IEVudHJlemdlbmUpIElEYCkgJT4lIAogIGxlZnRfam9pbiggLiwgcmVhZF90c3YoIGhlcmUoIi4uL3BRVExfd2Vic2l0ZS9fZGF0YS9wcm90ZW9taWNzRVNDLnR4dCIpICkgLCBieSA9IGMoImdlbmVJRCIgKSApICU+JSAKICBsZWZ0X2pvaW4oIGFsbF9vbWljc19pZHMpIAogIApkYW4uZ2VuZXMgPC0gZGF0YS5mcmFtZSgKICBtZ2lfc3ltYm9sID0gYygKICAgICJFc3JyYiIsICJLbGY0IiwgIk5hbm9nIiwgIlBvdTVmMSIsICJTb3gyIiwKICAgICJDaHJkIiwgIkZnZjgiLCAiT3R4MiIsICJQYXg2IiwgIlNveDEiLAogICAgIkdhdGE0IiwiR2F0YTYiLCAiUGRnZnJhIiwgIlNveDE3IiwgIlNveDciLCAKICAgICJCbXAyIiwiS2RyIiwgIk1peGwxIiwgIlQiLCAiV250M2EiCiAgKSwKICB0eXBlID0gYyhyZXAoInBsdXJpcG90ZW5jeSIsIDUpLCByZXAoImVjdG9kZXJtIiwgNSksIHJlcCgiZW5kb2Rlcm0iLCA1KSwgcmVwKCJtZXNvZGVybSIsIDUpKQopICU+JQogIGxlZnRfam9pbiguLCBhbGxfb21pY3NfaWRzKQpvcnRtYW5uX2dlbmVzIDwtIHRpYmJsZSgKICB0eXBlID0gYyggcmVwKCJwcmltaXRpdmUgZW5kb2Rlcm0iLDQpLAogICAgICAgICAgICAgICAgICAibmV1cmVjdG9kZXJtIiwgImRlZmluaXRpdmUgZW5kb2Rlcm0iLCAiZWN0b2Rlcm0iLCJlcGlibGFzdCIsCiAgICAgICAgICAgICAgICAgIHJlcCgiV250LXJlbGF0ZWQgZ2VuZXMiLDgpLAogICAgICAgICAgICByZXAoInBsdXJpcG90ZW5jeSIsOCkpLAogIG1naV9zeW1ib2wgPSBjKCAiR2F0YTYiLCJQZGdmcmEiLCJTb3g3IiwiU3BhcmMxIiwKICAgICAgICAgICAgICAgICAgIlNveDEiLCJTb3gxNyIsIk90eDIiLCJGZ2Y1IiwgCiAgICAgICAgICAgICJBeGluMiIsIkxlZjEiLCJDc25rMWUiLCAiR25haTEiLCAiTmtkMSIsICJUY2Y3IiwgIld3bnQ1YiIsICJGZ2ZybDEiLAogICAgICAgICAgICAiUG91NWYxIiwiTmFub2ciLCJLbGYyIiwiS2xmNCIsIkRwcGE1IiwiRXNycmIiLCJUZmNwMmwxIiwiU294MiIpCikKYWxsLmVzYy5nZW5lcyA8LSB0aWJibGUobWdpX3N5bWJvbCA9IAogICAgICAgICAgICAgICAgICAgICAgICAgIHVuaXF1ZShjKGVzY2FwZS5nZW5lcyRtZ2lfc3ltYm9sLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4dS5nZW5lcyRHZW5lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGthbGsuZ2VuZXMkR2VuZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRXR2NSIsIlJicGoiLCJGZ2YxNSIsIkR1c3A5IiwiSWQxIiwiSWQzIiwiSWQ0IikpICMgYWRkaW5nIHNvbWUgZnJvbSBvdGhlciBwYXBlcnMKICAgICAgICAgICAgICAgICAgICAgICAgKSAlPiUKICBsZWZ0X2pvaW4oYWxsX29taWNzX2lkcykgJT4lCiAgbXV0YXRlKHNfTWJwID0gKGdlbmVfc3RhcnQgLyAxZTA2KSAtIDAuMDAyLCBlX01icCA9IChnZW5lX2VuZCAvIDFlMDYpICsgMC4wMDIpCiMgZG93bmxvYWRpbmcgdGhlIGNjdmFyaWFudHMKIyBkb3dubG9hZC5maWxlKCJodHRwczovL25kb3dubG9hZGVyLmZpZ3NoYXJlLmNvbS9maWxlcy85NzQ2NDg1IiwgIl9kYXRhL2NjX3ZhcmlhbnRzLnNxbGl0ZSIpCiMgcmVhZCBpbiB2YXJpYW50IGRlZmluaXRpb25zCnZhci50eXBlcyA8LSByZWFkX3hsc3gocGF0aCA9IGhlcmUoIi4uL3BRVExfd2Vic2l0ZS9fZGF0YS9WYXJpYW50X0RlZmluaXRpb25zLnhsc3giKSkgJT4lCiAgcmVuYW1lKHR5cGUgPSBgU08gdGVybWAsIHNjb3JlID0gYEZ1bmN0aW9uYWwgY29uc2VxdWVuY2Ugc2NvcmVgKQoKYnVsdXQuZ2VuZXMgPC0gcmVhZHhsOjpyZWFkX3hsc3gocGF0aCA9IGhlcmUoIi4uL3BRVExfd2Vic2l0ZS9fZGF0YS9CdWx1dF8yMDE4X1RhYmxlUzYueGxzeCIpKSAlPiUKICByZW5hbWUobWdpX3N5bWJvbCA9IE9GRklDSUFMX0dFTkVfU1lNQk9MKSAlPiUKICBzZWxlY3QoLU5hbWUsIC1TcGVjaWVzKSAlPiUKICByb3d3aXNlKCkgJT4lCiAgbXV0YXRlKG1naV9zeW1ib2wgPSBwYXN0ZTAoc3Vic3RyKG1naV9zeW1ib2wsIDEsIDEpLCB0b2xvd2VyKHN1YnN0cihtZ2lfc3ltYm9sLCAyLCBuY2hhcihtZ2lfc3ltYm9sKSkpKSkgJT4lCiAgcmJpbmQodGliYmxlKG1naV9zeW1ib2wgPSBjKCJUaXA2MCIsICJFcDQwMCIsICJLYXQ1IiwgIkthdDgiLCAiSW5vODAiLCAiQXNoMmwiLCAiQ2hkMSIpKSkgJT4lICMgdGhlc2UgYXJlIG1lbnRpb25lZCBieSBuYW1lIGluIHRoZSBwYXBlcnMKICBsZWZ0X2pvaW4oYWxsX29taWNzX2lkcykKIyAyYy1saWtlIGNlbGwgZ2VuZXMgZnJvbSBIZW5kcmlja3NvbiAyMDE3LCB0YWJsZSBTOAojIGdldCB0aGUgZW5zZW1ibCBnZW5lIGlkcywgdGhleSBhcmUgZnJvbSBkZWNlbWJlciAyMDExIGFjYyB0byB0aGUgdGFibGUgZGV0YWlscwojIGZpbmQgbW9zdCByZWNlbnQgdmVyc2lvbnMgb2YgdGhlIGlkcyB1c2luZyBlbnNlbWJsIGlkIGNvbnZlcnRlcgojIFJlcXVlc3RlZCBJRAlNYXRjaGVkIElEKHMpCmdlbmVzXzJjIDwtIHJlYWRfeGxzeCggcGF0aCA9IGhlcmUoIi4uL3BRVExfd2Vic2l0ZS9fZGF0YSIsIkhlbmRyaWNrc29uXzIwMTdfdGFibGVTOF8yY2xpa2VfZ2VuZV9saXN0Lnhsc3giKSwgc2hlZXQgPSAyKSAlPiUgCiAgc2VsZWN0KCBlbnNlbWJsX2dlbmVfaWRfZGVjMjAxMSA9IGBSZXF1ZXN0ZWQgSURgLAkKICAgICAgICAgIGVuc2VtYmxfZ2VuZV9pZCA9IGBNYXRjaGVkIElEKHMpYCkgJT4lIAogIGxlZnRfam9pbiggYWxsX2Fubm90X3Y5OCkgJT4lCiAgbGVmdF9qb2luKCBhbGxfb21pY3NfaWRzKSAlPiUgCiAgZmlsdGVyKCAhaXMubmEobWdpX3N5bWJvbCkpIApgYGAKCmBgYHtyIGxvYWRfbWVkaWF0aW9ucywgd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgZWNobyA9RkFMU0V9CiMgbG9hZCBtZWRpYXRpb24gcmVzdWx0cwpsb2FkKGhlcmUoIi4uL3BRVExfd2Vic2l0ZS9fZGF0YS9ET19tRVNDX2VRVExfcHJvdGVpbl9tZWRpYXRpb25fbG9kNl92M19tZXJnZWQuUkRhdGEiKSkgIyBlcXRsX3JuYV9tZWRzCmxvYWQoaGVyZSgiLi4vcFFUTF93ZWJzaXRlL19kYXRhL0RPX21FU0NfZVFUTF9STkFfbWVkaWF0aW9uX2xvZDZfdjNfbWVyZ2VkLlJEYXRhIikpICMgZXF0bF9wcm90X21lZHMKbG9hZChoZXJlKCIuLi9wUVRMX3dlYnNpdGUvX2RhdGEvRE9fbUVTQ19wUVRMX3JuYV9tZWRpYXRpb25fbG9kNl9ub1BvbHlfdjRfbWVyZ2VkLlJEYXRhIikpICMgcHF0bF9ybmFfbWVkcwpsb2FkKGhlcmUoIi4uL3BRVExfd2Vic2l0ZS9fZGF0YS9ET19tRVNDX3BRVExfcHJvdGVpbl9tZWRpYXRpb25fbG9kNl9ub1BvbHlfdjQuUkRhdGEiKSkgIyByZXN1bHRzCnBxdGxfcHJvdF9tZWRzIDwtIHJlc3VsdHMKbG9hZChoZXJlKCIuLi9wUVRMX3dlYnNpdGUvX2RhdGEvRE9fbUVTQ19jYVFUTF9ybmFfbWVkaWF0aW9uX21lcmdlZF92Mi5SRGF0YSIpKQpsb2FkKGhlcmUoIi4uL3BRVExfd2Vic2l0ZS9fZGF0YS9ET19tRVNDX2NhUVRMX3Byb3RfbWVkaWF0aW9uX21lcmdlZF92Mi5SRGF0YSIpKQpgYGAKCmBgYHtyIG1pc2MsIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHJlc3VsdHM9ImhpZGUiICwgZWNobyA9RkFMU0V9CiMjIGxpZnIgZ2Vub3R5cGVzCiMgZ2V0X0xJRlJfZ2Vub3R5cGVzCiMgdXNpbmcgRGFuJ3MgY29kZSB0byBnZXQgTElGUiBnZW5vdHlwZXMgZm9yIHRoZSBmdWxsIGxpc3Qgb2YgYW5pbWFscwpwcm9icyA8LSBtZXJnZWQucHJvYnMKbWFya2VycyA8LSB0aWJibGUobmFtZSA9IGRpbW5hbWVzKHByb2JzW1sxNV1dKVtbM11dKSAlPiUKICBtdXRhdGUobmFtZTIgPSBuYW1lKSAlPiUKICBzZXBhcmF0ZShuYW1lMiwgaW50byA9IGMoImNocm9tIiwgInBvcyIpLCBzZXAgPSAiXyIsIGNvbnZlcnQgPSBUUlVFKQojIExJRnIgU05QIGlzIGNocjE1OjcxMTY5NDQgKHJzNTA0NTQ1NjYpCm1tIDwtIGZpbHRlcihtYXJrZXJzLCBjaHJvbSA9PSAiMTUiLCBwb3MgPiA3MDkwMDAwLCBwb3MgPCA3MTMwMDAwKSAjIDMgbWFya2Vycwpwcm9iczIgPC0gcHJvYnMkYDE1YFssICwgbW0kbmFtZV0KY2xvc2VzdF9nZW5vIDwtIGZ1bmN0aW9uKHAsIHRvbCA9IDAuMDEpIHsKICBpZiAoc3VtKGFicyhwIC0gYygxLCAwKSkpIDwgdG9sKSB7CiAgICByZXR1cm4oIkEiKQogIH0KICBpZiAoc3VtKGFicyhwIC0gYygwLCAxKSkpIDwgdG9sKSB7CiAgICByZXR1cm4oIkIiKQogIH0KICBpZiAoc3VtKGFicyhwIC0gYygwLjUsIDAuNSkpKSA8IHRvbCkgewogICAgcmV0dXJuKCJIIikKICB9CiAgcmV0dXJuKE5BKQp9CmNhbGxfZ2VubyA8LSBmdW5jdGlvbihtYXQpIHsKICAjIG1hdCBpcyBuc2FtcCo4IChoYXBzKQogICMgQSA9IEFfSgogICMgQiA9IEI2CiAgIyBDID0gMTI5CiAgIyBEID0gTk9ECiAgIyBFID0gTlpPCiAgIyBGID0gQ0FTVAogICMgRyA9IFBXSwogICMgSCA9IFdTQgogICMgSSB3YW50IHRvIGRpdmlkZSBOT0QgKyBDQVNUICsgUFdLICsgV1NCCiAgIyB2cy4gdGhlIG90aGVyIGZvdXIKICBncnAgPC0gYygiQSIsICJBIiwgIkEiLCAiQiIsICJBIiwgIkIiLCAiQiIsICJCIikKICBjb2xsYXBzZWQgPC0gYXBwbHkobWF0LCAxLCBmdW5jdGlvbih4KSB0YXBwbHkoeCwgZ3JwLCBzdW0pKQogIGFwcGx5KGNvbGxhcHNlZCwgMiwgY2xvc2VzdF9nZW5vKQp9CnByb2JzMyA8LSBhcHBseShwcm9iczIsIDMsIGNhbGxfZ2VubykKIyBhc3NlcnRfdGhhdChub05BKHByb2JzMykpCm9uZSA8LSBwcm9iczNbLCAxXSAjIG1hcmtlciBsZWZ0IG9mIExpZnIKdHdvIDwtIHByb2JzM1ssIDJdICMgY2xvc2VzdCBtYXJrZXIgdG8gTGlmcgp0aHJlZSA8LSBwcm9iczNbLCAzXSAjIG1hcmtlciByaWdodCBvZiBMaWZyCiMgIlBCMzYwLjQ5IiBoYXMgYW4gYW5jZXN0cnkgc3dpdGNoIGJldHdlZW4gbWFya2VycyAxICYgMiEKIyBHZXQgc2FtcGxlcyBpbiBncm91cCBBIChpbmJyZWQgc3RyYWlucykgYW5kIGdyb3VwIEIgKHdpbGQtZGVyaXZlZCArIE5PRCkKaW5icmVkIDwtIHJvd25hbWVzKHByb2JzW1sxXV0pW29uZSA9PSAiQSIgJiB0d28gPT0gIkEiICYgdGhyZWUgPT0gIkEiXQp3aWxkZGVyIDwtIHJvd25hbWVzKHByb2JzW1sxXV0pW29uZSA9PSAiQiIgJiB0d28gPT0gIkIiICYgdGhyZWUgPT0gIkIiXQpoZXRzIDwtIHJvd25hbWVzKHByb2JzW1sxXV0pW29uZSA9PSAiSCIgJiB0d28gPT0gIkgiICYgdGhyZWUgPT0gIkgiXQojIGNhdChpbmJyZWQsIHNlcD0iXG4iLCBmaWxlPSJsaWZyX2dlbm90eXBlX2luYnJlZC50eHQiKQojIGNhdCh3aWxkZGVyLCBzZXA9IlxuIiwgZmlsZT0ibGlmcl9nZW5vdHlwZV93aWxkZGVyLnR4dCIpCiMgY2F0KGhldHMsIHNlcD0iXG4iLCBmaWxlPSJsaWZyX2dlbm90eXBlX2hldC50eHQiKQojCmRhdGFfZnJhbWUoCiAgbGlmcl9nZW5vID0gZmFjdG9yKGMocmVwKCJSZWYiLCBsZW5ndGgoaW5icmVkKSksIGMocmVwKCJBbHQiLCBsZW5ndGgod2lsZGRlcikpKSwgYyhyZXAoIkhldCIsIGxlbmd0aChoZXRzKSkpKSksCiAgbGlmciA9IGZhY3RvcihjKHJlcCgwLCBsZW5ndGgoaW5icmVkKSksIGMocmVwKDEsIGxlbmd0aCh3aWxkZGVyKSkpLCBjKHJlcCgyLCBsZW5ndGgoaGV0cykpKSkpLAogIHJvd25hbWUgPSBjKChpbmJyZWQpLCAod2lsZGRlciksIChoZXRzKSkKKSAlPiUKICBtdXRhdGUocm93bmFtZSA9IGlmZWxzZShpcy5uYShyb3duYW1lKSwgIkE5MDNESTFDLkMxMiIsIHJvd25hbWUpKSAtPiBjb3Zhci5saWZyCgptZXJnZWQuY292YXIgJT4lCiAgYXMuZGF0YS5mcmFtZSgpICU+JQogIHJvd25hbWVzX3RvX2NvbHVtbigpICU+JQogIGZ1bGxfam9pbihjb3Zhci5saWZyKSAlPiUKICBjb2x1bW5fdG9fcm93bmFtZXMoInJvd25hbWUiKSAtPiBtZXJnZWQuY292YXIyCm1lcmdlZC5jb3ZhcjMgPC0gbW9kZWwubWF0cml4KH4gc2V4ICsgbGlmciwgbWVyZ2VkLmNvdmFyMilbLCAtMV0Kc2hhcmVkLnByb2JzIDwtIG1lcmdlZC5wcm9ic1tpbmQgPSB0aHJlZXdheS5zaGFyZWQuc2FtcGxlcyR0b3BfbXVnYV0KYXR0cmlidXRlcyhzaGFyZWQucHJvYnMpJGlzX3hfY2hyIDwtICBhdHRyaWJ1dGVzKHByb2JzLmVzY19hdGFjKSRpc194X2NocgpzaGFyZWQuY292YXIgPC0gbWVyZ2VkLmNvdmFyWyB0aHJlZXdheS5zaGFyZWQuc2FtcGxlcyR0b3BfbXVnYSwsZHJvcD1GQUxTRV0Kc2hhcmVkLmtpbnNoaXAgPC0gY2FsY19raW5zaGlwKHNoYXJlZC5wcm9icywgdHlwZSA9ICJsb2NvIikKCiMgcHJlcCBzb21lIHN0dWZmIGZvciBwbG90dGluZzoKdWNociA8LSBjKGFzLmNoYXJhY3RlcigxOjE5KSwgIlgiKQpjbCA8LSBkcGx5cjo6c2VsZWN0KG1hcF9kYXQyLCBjaHIsIHBvc19icCkgJT4lCiAgZ3JvdXBfYnkoY2hyKSAlPiUKICBkcGx5cjo6c3VtbWFyaXplKGxlbiA9IG1heChwb3NfYnApKQpjbHAgPC0gd2l0aChjbCwgc2V0TmFtZXMobGVuLCBjaHIpKQpjaHJvbV9sZW5zIDwtIHNldE5hbWVzKGFzLm51bWVyaWMoY2xwW3VjaHJdKSwgdWNocikKY2hyb21fbGVuc19vZmZzZXQgPC0gY3Vtc3VtKGNocm9tX2xlbnMpIC0gY2hyb21fbGVucwpjaHJvbV9sZW5zX21pZHB0IDwtIGNocm9tX2xlbnNfb2Zmc2V0ICsgY2hyb21fbGVucyAvIDIKYWxsLmdlbmVzMiA8LSBhbGwuZ2VuZXMgJT4lIG11dGF0ZShtaWRwb2ludCA9IChnZW5lX3N0YXJ0ICsgZ2VuZV9lbmQpIC8gMikKYWxsLmdlbmVzMiRjdW1zdW1fYnBfZ2VuZSA8LSBhbGwuZ2VuZXMyJG1pZHBvaW50ICsgY2hyb21fbGVuc19vZmZzZXRbYWxsLmdlbmVzMiRnZW5lX2Nocl0KYWxsLnByb3RzMiA8LSBhbGwucHJvdHMgJT4lIG11dGF0ZShtaWRwb2ludCA9IChnZW5lX3N0YXJ0ICsgZ2VuZV9lbmQpIC8gMikKYWxsLnByb3RzMiRjdW1zdW1fYnBfZ2VuZSA8LSBhbGwucHJvdHMyJG1pZHBvaW50ICsgY2hyb21fbGVuc19vZmZzZXRbYWxsLnByb3RzMiRnZW5lX2Nocl0KbWFwX2RhdDIgPC0gcmVuYW1lKG1hcF9kYXQyLCBwb3NfY00gPSBwb3MpCm1hcF9kYXQyIDwtIG11dGF0ZShtYXBfZGF0MiwgcG9zX2NNID0gYXMubnVtZXJpYyhwb3NfY00pKQoKIyAgcm5hIC8gcHJvdCAvIGNocm9tYXRpbgpxdGwuY29sb3JzIDwtIGMoIHJuYSA9ICIjMjI4ODMzIiwgCiAgICAgICAgICAgICAgICAgcHJvdCA9ICIjNDQ3N0FBIiwgCiAgICAgICAgICAgICAgICAgYXRhYyA9ICIjRUU2Njc3IiwKICAgICAgICAgICAgICAgICBzaGFyZWQgPSAiI0FBMzM3NyIpCiNmb3VuZGVyX2NvbG9ycyA8LSBjKCIjRkZEQzAwIiwgIiM4ODg4ODgiLCAiI0YwODA4MCIsICIjMDA2NEM5IiwgIiM3RkRCRkYiLCAiIzJFQ0M0MCIsICIjRkY0MTM2IiwgIiNCMTBEQzkiKQpmb3VuZGVyX2NvbG9ycyA8LSBjKEFKID0gIiNGMEU0NDIiLCBCNiA9ICIjNTU1NTU1IiwgYDEyOWAgPSAiI0U2OUYwMCIsIE5PRCA9ICIjMDA3MkIyIiwKICAgTlpPID0gIiM1NkI0RTkiLCBDQVNUID0gIiMwMDlFNzMiLCBQV0sgPSAiI0Q1NUUwMCIsIFdTQiA9ICIjQ0M3OUE3IikKIyMgYWRkaW5nIGNjX3ZhcmlhbnRzIGZvciBhc3NvY2lhdGlvbiBtYXBwaW5nCnF1ZXJ5X3ZhcmlhbnRzIDwtIGNyZWF0ZV92YXJpYW50X3F1ZXJ5X2Z1bmMoaGVyZSgiLi4vcFFUTF93ZWJzaXRlL19kYXRhL2NjX3ZhcmlhbnRzLnNxbGl0ZSIpKQpxdWVyeV9nZW5lcyA8LSBjcmVhdGVfZ2VuZV9xdWVyeV9mdW5jKGhlcmUoIi4uL3BRVExfd2Vic2l0ZS9fZGF0YS9tb3VzZV9nZW5lc19tZ2kuc3FsaXRlIikpCiMgc2V4IGNhbGxzIGZyb20gQWxleCBTdGFudG9uIHJldHJpZXZlZCB2aWEgc2xhY2sgb24gSnVseSAyOCwgMjAyMApzZXhfY2FsbHMgPC0gcmVhZF9jc3YoaGVyZSgiLi4vcFFUTF93ZWJzaXRlL19kYXRhL3Bsb2lkeXN0YXR1c19BU18wNzI4MjAyMC5jc3YiKSkKIyBmb3IgTE9MQQpyZWdpb25EQiA9IGxvYWRSZWdpb25EQihoZXJlKCJfZGF0YS9MT0xBL25tL3QxL3Jlc291cmNlcy9yZWdpb25zL0xPTEFDb3JlL21tMTAvIikpCgpgYGAKCgpgYGB7ciBzYXZlX1JEYXRhX2Zvcl9maWdzaGFyZSwgZWNobz1GQUxTRSwgZXZhbD1GQUxTRX0KCiMgMS4JUHJvdGVvbWljcyBkYXRhOiBET19tRVNDX3Byb3Rlb21pY3MuUkRhdGEgZmlsZSBjb250YWlucyB0aGUgZm9sbG93aW5nIG9iamVjdHMuCiMg4oCiCWV4cHIuZXNjX3Byb3QKIyDigKIJZXhwclouZXNjX3Byb3QKIyDigKIJYWxsLnByb3RzCiMg4oCiCXByb2JzLmVzY19wcm90CiMg4oCiCWNvdmFyLmVzY19wcm90CiMg4oCiCWNvdmFyVGlkeS5lc2NfcHJvdAojIOKAoglraW5zaGlwX2xvY28uZXNjX3Byb3QKIyDigKIJcG1hcCwgZ21hcCwgbWFwX2RhdDIKCmNvdmFyVGlkeS5lc2NfcHJvdCA8LSBsZWZ0X2pvaW4oY292YXJUaWR5LmVzY19wcm90LCBjb3Zhci5saWZyLCBieSA9IGMoInRvcF9tdWdhIj0icm93bmFtZSIpKQoKc2F2ZSggZmlsZSA9IGhlcmUoIl9maWdzaGFyZSIsIkRPX21FU0NfcHJvdGVvbWljcy5SRGF0YSIpLAogICAgICBleHByLmVzY19wcm90LAogICAgICBleHByWi5lc2NfcHJvdCwgCiAgICAgIGFsbC5wcm90cywgCiAgICAgIHNoYXJlZC5nZW5lcywgCiAgICAgIHNoYXJlZC5zYW1wbGVzLAogICAgICBwcm9icy5lc2NfcHJvdCwKICAgICAgY292YXIuZXNjX3Byb3QsCiAgICAgIGNvdmFyVGlkeS5lc2NfcHJvdCwKICAgICAga2luc2hpcF9sb2NvLmVzY19wcm90LAogICAgICBwbWFwLAogICAgICBnbWFwLAogICAgICBtYXBfZGF0MikKCiMgMi4JQ29tcGxleGVzOiBUaGUgbGlzdCBvZiBwcm90ZWluIGNvbXBsZXhlcyBhbmQgdGhlIGdlbmVzIHdpdGhpbiB0aGVtIGFzIHJldHJpZXZlZCBmcm9tIE9yaSBldCBhbC4sIDIwMTYxLgpzYXZlKCBjb21wbGV4ZXMsCiAgICAgIGZpbGUgPSBoZXJlKCJfZmlnc2hhcmUiLCJDb21wbGV4X2dlbmVfbGlzdC5SRGF0YSIpCikKCiMgMy4JRGF0YSB1c2VkIGluIGNvdmFyaWF0aW9uIGFuYWx5c2lzOiBET19tRVNDX2NvdmFyLlJEYXRhIGZpbGUgY29udGFpbnMgdGhlIGZvbGxvd2luZyBvYmplY3RzOgojIOKAoglleHByLmVzY19ybmEKIyDigKIJYWxsLmdlbmVzCiMg4oCiCWFsbC50ZnMKIyDigKIJY291bnRzLm5vcm0yCiMg4oCiCXRocmVld2F5LnNoYXJlZC5zYW1wbGVzCiMg4oCiCXRocmVld2F5LnNoYXJlZC5nZW5lcwojIOKAoglhdGFjLnBlYWsuYW5ub3RzCgpzYXZlKAogIGV4cHIuZXNjX3JuYSwKICBhbGwuZ2VuZXMsIAogIGFsbC50ZnMsCiAgY291bnRzLm5vcm0yLAogIHRocmVld2F5LnNoYXJlZC5nZW5lcywKICB0aHJlZXdheS5zaGFyZWQuc2FtcGxlcywKICBhdGFjLnBlYWsuYW5ub3RzLAogIGZpbGUgPSBoZXJlKCJfZmlnc2hhcmUiLCJET19tRVNDX2NvdmFyLlJEYXRhIikKKQoKIyA0LglwUVRMIGRhdGE6IERPX21FU0NfcFFUTC5SRGF0YSBmaWxlIGNvbnRhaW5zIHRoZSBmb2xsb3dpbmcgb2JqZWN0cy4KIyDigKIJZXNjLnByb3Quc2NhbnMg4oCTIHBRVEwgc2NhbnMgZm9yIGFsbCA3LDQzMiBwcm90ZWlucy4KIyDigKIJZXNjLnJuYS5zY2FucwojIOKAoglwcXRsX3Byb3RfbWVkcyDigJMgTWVkaWF0aW9uIHJlc3VsdHMgb2YgcFFUTCBwZWFrcyB1c2luZyBwcm90ZWluIGFidW5kYW5jZXMuCiMg4oCiCXBxdGxfcm5hX21lZHMg4oCTIE1lZGlhdGlvbiByZXN1bHRzIG9mIHBRVEwgcGVha3MgdXNpbmcgdHJhbnNjcmlwdCBhYnVuZGFuY2VzLgojIOKAoglkb19tZXNjX3BxdGxfcGVybXMg4oCTIFBlcm11dGF0aW9uIHJlc3VsdHMgd2l0aCBhbHBoYSA9IDAuMDUgZm9yIGFsbCA3LDQzMiBwcm90ZWlucy4KbG9hZCgiL3Byb2plY3RzL211bmdlci1sYWIvcHJvamVjdHMvRE9fbUVTQy9wcm90ZW9taWNzL3BxdGxfbWFwcGluZ19TQS9ETzE5NV9tRVNDX3BRVExfc2NhbnNfbm9Qb2x5X3YyLlJEYXRhIikgIyBlc2MucHJvdC5zY2Fucwpsb2FkKCIvcHJvamVjdHMvbXVuZ2VyLWxhYi9wcm9qZWN0cy9ET19tRVNDL3JuYV9zZXEvcXRsX21hcHBpbmcvdG90YWxfZ2VuZV9leHByZXNzaW9uL2VxdGxfZ3JpZDY5a19wZS9ETzE4NV9tRVNDX3BhaXJlZF9lUVRMX3NjYW5zLlJEYXRhIikgIyBlc2Mucm5hLnNjYW5zCmRvX21lc2NfcHF0bF9wcm90X21lZHMgPC0gcHF0bF9wcm90X21lZHMKZG9fbWVzY19wcXRsX3JuYV9tZWRzICA8LSBwcXRsX3JuYV9tZWRzCiMgbmVlZCB0byBsb2FkIHRoZSBwZXJtdXRhdGlvbiByZXN1bHRzIHRvbwojIGxvYWQgYW5kIG9ubHkga2VlcCB0aGUgYWxwaGEgPSAuMDUgcmVzdWx0cwpsb2FkKGhlcmUoIi9wcm9qZWN0cy9tdW5nZXItbGFiL3Byb2plY3RzL0RPX21FU0MvcHJvdGVvbWljcy9wcXRsX21hcHBpbmdfU0EvcFFUTF9wZXJtc18wMV8wMDUuUkRhdGEiKSkKZG9fbWVzY19wcXRsX3Blcm1zIDwtIHBlcm1zICU+JSAKICBmaWx0ZXIoYWxwaGEgPT0gMC4wNSkKcm0ocGVybXMpCgpzYXZlKAogIGVzYy5wcm90LnNjYW5zLAogIGVzYy5ybmEuc2NhbnMsCiAgcHF0bF9wcm90X21lZHMsCiAgcHF0bF9ybmFfbWVkcywKICBkb19tZXNjX3BxdGxfcGVybXMsCiAgZmlsZSA9IGhlcmUoIl9maWdzaGFyZSIsIkRPX21FU0NfcFFUTC5SRGF0YSIpCikKCiMgNS4JT3ZlcmxhcCBhY3Jvc3MgUVRMIHBlYWtzIGRhdGE6IAojIOKAoglwZWFrcy5lc2NfcHJvdAojIOKAoglwZWFrcy5lc2Mub3ZlcmxhcC53RWZmcwojIOKAoglleHByWi5lc2Nfcm5hLCBwcm9icy5lc2Nfcm5hLCBjb3Zhci5lc2Nfcm5hLCBraW5zaGlwX2xvY28uZXNjX3JuYQojIOKAogljb3VudHMubm9ybVosIHByb2JzLmVzY19hdGFjLCBjb3Zhci5lc2NfYXRhYywga2luc2hpcF9sb2NvLmVzY19hdGFjCiMg4oCiCXRocmVld2F5LnNoYXJlZC5zYW1wbGVzCiMg4oCiCXRocmVld2F5LnNoYXJlZC5nZW5lcwpzYXZlKAogIHBlYWtzLmVzY19wcm90LAogIHBlYWtzLmVzYy5vdmVybGFwLndFZmZzLAogIGV4cHJaLmVzY19ybmEsIHByb2JzLmVzY19ybmEsIGNvdmFyLmVzY19ybmEsIGtpbnNoaXBfbG9jby5lc2Nfcm5hLAogIGNvdW50cy5ub3JtWiwgcHJvYnMuZXNjX2F0YWMsIGNvdmFyLmVzY19hdGFjLCBraW5zaGlwX2xvY28uZXNjX2F0YWMsCiAgdGhyZWV3YXkuc2hhcmVkLnNhbXBsZXMsCiAgdGhyZWV3YXkuc2hhcmVkLmdlbmVzLAogIGZpbGUgPSBoZXJlKCJfZmlnc2hhcmUiLCJET19tRVNDX1FUTF9wZWFrcy5SRGF0YSIpCikKCiMgNi4JRGF0YSB1c2VkIGluIE1PRkEgYW5kIGludGVncmF0aW9uIHJlc3VsdHM6IERPX21FU0NfTU9GQS5SRGF0YQojIOKAoglhbGxfZGZfc2hhcmVkCiMg4oCiCWFsbF9kZl9zaGFyZWRfbW9kZWwKIyDigKIJc2hhcmVkX3NhbXBsZXNfbWV0YWRhdGEKIyDigKIJc2hhcmVkLnByb2JzCiMg4oCiCXNoYXJlZC5raW5zaGlwCiMg4oCiCXNoYXJlZC5jb3ZhcgoKIyDigKIJZ21hcCwgcG1hcCwgbWFwX2RhdDIKCgpsaWJyYXJ5KE1PRkEyKQojIGxvYWQgZGF0YSBmcm9tIHRoZSBNT0ZBIHByb2plY3QKbG9hZCgiL3Byb2plY3RzL211bmdlci1sYWIvcHJvamVjdHMvRE9fbUVTQy9wcm90ZW9taWNzL3BRVExfd2Vic2l0ZS9fZGF0YS9NT0ZBX2RhdGFfcHJlcF8wNDExMjAyMi5SRGF0YSIpICMgaGFzIGFsbCB0aGUgZGF0YSBmcmFtZXMKcm0oYWxsX2RmLCAKICAgYWxsX2RmX3RvcDVrLCBhbGxfZGZfdG9wNWtfc2hhcmVkLAogICB0cmFuc19kZl90b3AxNWssIHRyYW5zX2RmX3RvcDE1a19zaGFyZWQsCiAgIGhlcml0X2RmX3NoYXJlZCkKCiMgbG9hZCBNT0ZBIG1vZGVsICsgcHJvY2VzcyBpdAojIGNyZWF0ZSB0aGUgTU9GQSBvYmplY3QKYWxsX2RmX3NoYXJlZF9NT0ZBb2JqZWN0IDwtIGNyZWF0ZV9tb2ZhKGFsbF9kZl9zaGFyZWQpCgojIExvYWQgaW4gbW9kZWwgcmVzdWx0cyBnZW5lcmF0ZWQgdXNpbmcgX3NyYy9NT0ZBX3RyYWluX21vZGVsX0NQVS5yCmFsbF9kZl9zaGFyZWRfbW9kZWwgPC0gbG9hZF9tb2RlbChoZXJlKCIuLi9wUVRMX3dlYnNpdGUvX2RhdGEvYWxsX2RmX3NoYXJlZF8zMGZhY3RvcnNfMjAyMi0wNC0xMS5oZGY1IiksIHJlbW92ZV9pbmFjdGl2ZV9mYWN0b3JzID0gRikKIyBXYXJuaW5nIG1lc3NhZ2U6CiMgSW4gLnF1YWxpdHlfY29udHJvbChvYmplY3QsIHZlcmJvc2UgPSB2ZXJib3NlKSA6CiMgICBGYWN0b3IocykgMyBhcmUgc3Ryb25nbHkgY29ycmVsYXRlZCB3aXRoIHRoZSB0b3RhbCBudW1iZXIgb2YgZXhwcmVzc2VkIGZlYXR1cmVzIGZvciBhdCBsZWFzdCBvbmUgb2YgeW91ciBvbWljcy4gU3VjaCBmYWN0b3JzIGFwcGVhciB3aGVuIHRoZXJlIGFyZSBkaWZmZXJlbmNlcyBpbiB0aGUgdG90YWwgJ2xldmVscycgYmV0d2VlbiB5b3VyIHNhbXBsZXMsICpzb21ldGltZXMqIGJlY2F1c2Ugb2YgcG9vciBub3JtYWxpc2F0aW9uIGluIHRoZSBwcmVwcm9jZXNzaW5nIHN0ZXBzLgoKIyBSZW1vdmluZyBGYWN0b3IgMyB0aGF0IHNob3dzIGhpZ2ggY29ycmVsYXRpb24gdG8gdGhlIHRvdGFsICMgb2YgZXhwcmVzc2VkIGZlYXR1cmVzLgphbGxfZGZfc2hhcmVkX21vZGVsIDwtIHN1YnNldF9mYWN0b3JzKCBhbGxfZGZfc2hhcmVkX21vZGVsLCBmYWN0b3JzID0gYygxOjIsIDQ6MzApKQoKIyBSZW1vdmluZyBGYWN0b3JzIHRoYXQgZG9uJ3QgZXhwbGFpbiBhdCBsZWFzdCAxJSBvZiB2YXJpYXRpb24gaW4gYSBkYXRhIHNldC4gCmFsbF9kZl9zaGFyZWRfZmFjdG9yX3ZhciA8LSBhbGxfZGZfc2hhcmVkX21vZGVsQGNhY2hlJHZhcmlhbmNlX2V4cGxhaW5lZCRyMl9wZXJfZmFjdG9yICU+JQogIGFzLmRhdGEuZnJhbWUoKSAlPiUKICByb3duYW1lc190b19jb2x1bW4oKSAlPiUKICBmaWx0ZXIoc2luZ2xlX2dyb3VwLkNocm9tYXRpbiA+IDEgfAogICAgICAgICAgIHNpbmdsZV9ncm91cC5Qcm90ZWluID4gMSB8CiAgICAgICAgICAgc2luZ2xlX2dyb3VwLlRyYW5zY3JpcHQgPiAxKSAlPiUKICBjb2x1bW5fdG9fcm93bmFtZXMoKQphbGxfZGZfc2hhcmVkX21vZGVsX2ZpbHRlcmVkIDwtIHN1YnNldF9mYWN0b3JzKGFsbF9kZl9zaGFyZWRfbW9kZWwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWN0b3JzID0gYXMubnVtZXJpYyhnc3ViKCJGYWN0b3IiLCIiLHJvd25hbWVzKGFsbF9kZl9zaGFyZWRfZmFjdG9yX3ZhcikpKSkKCiMgdXBkYXRpbmcgdGhlIHNleGVzIGluIHRoZSBtZXRhZGF0YSB0byB1c2UgRmVtYWxlL01hbGUgaW5zdGVhZCBvZiAwcyBhbmQgMXMuCm1lcmdlZF9tZXRhZGF0YSA8LSBtZXJnZWQuY292YXIyICU+JQogIGFzLmRhdGEuZnJhbWUoKSAlPiUKICByb3duYW1lc190b19jb2x1bW4oKSAlPiUKICBzZWxlY3QoLWxpZnIpICU+JQogIHJlbmFtZSgic2FtcGxlIj0icm93bmFtZSIpCnNoYXJlZF9zYW1wbGVzX21ldGFkYXRhIDwtIGFsbF9kZl9zaGFyZWRfbW9kZWxfZmlsdGVyZWRAc2FtcGxlc19tZXRhZGF0YSAlPiUKICBsZWZ0X2pvaW4oLixtZXJnZWRfbWV0YWRhdGEpICU+JQogIG11dGF0ZShzZXggPSBpZmVsc2Uoc2V4ID09MCwiRmVtYWxlIiwgIk1hbGUiKSkKc2FtcGxlc19tZXRhZGF0YShhbGxfZGZfc2hhcmVkX21vZGVsX2ZpbHRlcmVkKSA8LSBzaGFyZWRfc2FtcGxlc19tZXRhZGF0YQoKIyBHZXQgRmFjdG9yIHdlaWdodHMKYWxsX2RmX3NoYXJlZF9mYWN0b3JzIDwtIGdldF9mYWN0b3JzKGFsbF9kZl9zaGFyZWRfbW9kZWxfZmlsdGVyZWQsCiAgZmFjdG9ycyA9ICJhbGwiLAogIGFzLmRhdGEuZnJhbWUgPSBUCikKIyBBZGQgc2FtcGxlIGRldGFpbHMgYW5kIGNvbnZlcnQgdG8gbWF0cml4IHdpdGggRmFjdG9ycyBpbiByb3dzIGFuZCBzYW1wbGVzIGluIGNvbHVtbnMuCmFsbF9kZl9zaGFyZWRfZmFjdG9yc19tYXQgPC0gYWxsX2RmX3NoYXJlZF9mYWN0b3JzICU+JQogIHBpdm90X3dpZGVyKGlkX2NvbHMgPSAic2FtcGxlIiwgbmFtZXNfZnJvbSA9ICJmYWN0b3IiLCB2YWx1ZXNfZnJvbSA9ICJ2YWx1ZSIpICU+JQogIGxlZnRfam9pbiguLCBzZWxlY3QodGhyZWV3YXkuc2hhcmVkLnNhbXBsZXMsIHRvcF9tdWdhLCBzYW1wbGVpZCksIGJ5ID1jKCJzYW1wbGUiPSJ0b3BfbXVnYSIpKSAlPiUKICBjb2x1bW5fdG9fcm93bmFtZXMoInNhbXBsZSIpICU+JQogIHNlbGVjdCgtc2FtcGxlaWQpICU+JQogIGFzLm1hdHJpeCgpCgojIEdldCBmZWF0dXJlIHdlaWdodHMKYWxsX2RmX3NoYXJlZF93ZWlnaHRzIDwtIGdldF93ZWlnaHRzKGFsbF9kZl9zaGFyZWRfbW9kZWxfZmlsdGVyZWQsIGFzLmRhdGEuZnJhbWUgPSBUUlVFLCBzY2FsZSA9IFRSVUUpCgojIGxvYWQgaW4gcGVybXV0YXRpb24gcmVzdWx0cwpsb2FkKGhlcmUoIi4uL3BRVExfd2Vic2l0ZS9fZGF0YS9NT0ZBX2FsbF9kZl90aHJlc19yYW5rWi5SRGF0YSIpKQoKIyBsb2FkIGluIGNvbWJpbmVkIGxvbGEgcmVzdWx0cwpsb2FkKCBoZXJlKCIuLi9wUVRMX3dlYnNpdGUvX2RhdGEvIiwiTU9GQV9GYWN0b3JfTE9MQV9yZXN1bHRzLlJEYXRhIikpICMgbG9sYV9jb21iaW5lZAoKIyBzYXZpbmcKc2F2ZSgKICBhbGxfZGZfc2hhcmVkLAogIGFsbF9kZl9zaGFyZWRfbW9kZWwsCiAgI2FsbF9kZl9zaGFyZWRfbW9kZWxfZmlsdGVyZWQsCiAgc2hhcmVkX3NhbXBsZXNfbWV0YWRhdGEsCiAgI2FsbF9kZl9zaGFyZWRfZmFjdG9ycywKICAjYWxsX2RmX3NoYXJlZF93ZWlnaHRzLAogICNhbGxfZGZfc2hhcmVkX2ZhY3RvcnNfbWF0LAogIHNoYXJlZC5wcm9icywKICBzaGFyZWQua2luc2hpcCwKICBzaGFyZWQuY292YXIsCiAgZ21hcCwgcG1hcCwgbWFwX2RhdDIsCiAgYWxsX2RmX3NoYXJlZF90aHJlcywKICBsb2xhX2NvbWJpbmVkLAogIGZpbGUgPSBoZXJlKCJfZmlnc2hhcmUiLCJET19tRVNDX01PRkEuUkRhdGEiKQopCgpgYGAKCgo8YnI+IDxicj4KCiMjIyBGaWd1cmUgMUE6IE92ZXJ2aWV3IG9mIGRhdGEgc2V0cwoKYGBge3IgRmlndXJlMUEsIGZpZy5jYXAgPSAiRmlndXJlIDFBOiBOZWFybHkgMjAwIGVtYnJ5b25pYyBzdGVtIGNlbGwgbGluZXMgd2VyZSBlc3RhYmxpc2hlZCBmcm9tIGJsYXN0b2N5c3RzIG9mIERpdmVyc2l0eSBPdXRicmVkIG1pY2UsIGFuZCBxdWFudGlmaWVkIHVzaW5nIEFUQUMtc2VxLCBSTkEtc2VxIChTa2VsbHkgZXQgYWwuLCAyMDIwKSwgYW5kIG11bHRpcGxleGVkIG1hc3Mgc3BlY3Ryb21ldHJ5OyAxNjMgbGluZXMgaGF2ZSBhbGwgdGhyZWUgbWVhc3VyZXMuIn0KCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKGhlcmUoIkZpZ3VyZTFBLnBuZyIpKQoKYGBgCgo8YnI+CgojIyMjIFRhYmxlIFMxLlF1YW50aXRhdGl2ZSBwcm90ZW9taWMgYW5hbHlzaXMgb2YgRE8gbUVTQ3MuCgpUYWJsZSBjb250YWluaW5nIG5vcm1hbGl6ZWQgYW5kIGZpbHRlcmVkIHByb3RlaW4gYWJ1bmRhbmNlcyAobiA9IDcsNDMyKSBhY3Jvc3MgaW5kaXZpZHVhbCBETyBtRVNDbGluZXMgKG4gPSAxOTApIGFuZCBETyBtRVNDIGxpbmUgZGV0YWlscyB3aXRoIGV4cGVyaW1lbnRhbCBjb3ZhcmlhdGVzIHNleCBhbmQgZ2Vub3R5cGUgYXQgdGhlICpMaWZyKiBsb2N1cy4KCgoKYGBge3IgVGFibGVTMV9zaGVldDEsIGVjaG8gPSBGQUxTRX0KCiMgZXhwci5lc2NfcHJvdCAlPiUKIyAgIGFzX3RpYmJsZSggcm93bmFtZXMgPSAic2FtcGxlaWQiKSAlPiUKIyAgIHBpdm90X2xvbmdlciggY29scyA9IDI6NzQzMywgbmFtZXNfdG8gPSAicHJvdGVpbl9pZCIsIHZhbHVlc190byA9ICJwcm90ZWluX2FidW5kYW5jZSIpICU+JQojICAgbGVmdF9qb2luKCBhbGwucHJvdHMpICU+JQojICAgc2VsZWN0KCBzYW1wbGVpZCwgbWdpX3N5bWJvbCwgcHJvdGVpbl9pZCwgcHJvdGVpbl9hYnVuZGFuY2UgKSAlPiUKIyAgIHBpdm90X3dpZGVyKCBpZF9jb2xzID0gYygicHJvdGVpbl9pZCIsIm1naV9zeW1ib2wiKSwKIyAgICAgICAgICAgICAgICBuYW1lc19mcm9tID0gInNhbXBsZWlkIiwKIyAgICAgICAgICAgICAgICB2YWx1ZXNfZnJvbSA9ICJwcm90ZWluX2FidW5kYW5jZSIpICU+JQojICAgI211dGF0ZV9pZiggaXMubnVtZXJpYywgZm9ybWF0QywgZm9ybWF0ID0gImZnIiwgZGlnaXRzID0yICkgJT4lCiMgICByZW5hbWUoIGBQcm90ZWluIElEYCA9IHByb3RlaW5faWQsCiMgICAgICAgICAgIGBNR0kgU3ltYm9sYCA9IG1naV9zeW1ib2wpIC0+IHByb3RlaW5fYWJ1bmRhbmNlCiMgCiMgCiMgY292YXJUaWR5LmVzY19wcm90ICU+JQojICAgbGVmdF9qb2luKGNvdmFyLmxpZnIsIGJ5ID0gYygidG9wX211Z2EiPSJyb3duYW1lIikpICU+JQojICAgc2VsZWN0KHNhbXBsZWlkLCBzZXgsIGxpZnJfZ2VubykgJT4lCiMgICBtdXRhdGUoIHNleCA9IGlmZWxzZSggc2V4ID09ICJNIiwgIk1hbGUiLCAiRmVtYWxlIikpICU+JQojICAgcmVuYW1lKCBgR2Vub3R5cGUgYXQgTGlmcmAgPSBsaWZyX2dlbm8sCiMgICAgICAgICAgIGBTYW1wbGUgSURgID0gc2FtcGxlaWQsCiMgICAgICAgICAgIFNleCA9IHNleCkgLT4gc2FtcGxlX2RldGFpbHMKIyAKIyB3cml0ZXhsOjp3cml0ZV94bHN4KCBsaXN0KCBQcm90ZWluX2FidW5kYW5jZSA9IHByb3RlaW5fYWJ1bmRhbmNlLAojICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU2FtcGxlX2RldGFpbHMgPSBzYW1wbGVfZGV0YWlscyksCiMgICAgICAgICAgICAgICAgICAgICBwYXRoID0gaGVyZSgiVGFibGVTMV9ET19tRVNDX1Byb3Rlb21lcy54bHN4IiksCiMgICAgICAgICAgICAgICAgICAgICBjb2xfbmFtZXMgPSBUUlVFLAojICAgICAgICAgICAgICAgICAgICAgZm9ybWF0X2hlYWRlcnMgPSBUUlVFCiMgICAgICAgICAgICAgICAgICAgICApCgoKIyB4ZnVuOjplbWJlZF9maWxlKGhlcmUoIlRhYmxlX1MxLnhsc3giKSkKCmRvd25sb2FkX2ZpbGUoCiAgcGF0aCA9ICBoZXJlKCJUYWJsZV9TMS54bHN4IiksCiAgb3V0cHV0X25hbWUgPSAiVGFibGVfUzEiLAogIGJ1dHRvbl9sYWJlbCA9ICJEb3dubG9hZCBUYWJsZV9TMS54bHN4IiwKICBidXR0b25fdHlwZSA9ICJwcmltYXJ5IiwKICBoYXNfaWNvbiA9IFRSVUUsCiAgaWNvbiA9ICJmYSBmYS1zYXZlIiwKICBzZWxmX2NvbnRhaW5lZCA9IEZBTFNFCikKCmBgYAoKPGJyPgoKQW5ub3RhdGlvbnMgZm9yIGFsbCBwcm90ZWlucyBpbiBvdXIgZGF0YSBzZXQgY2FuIGJlIGRvd25sb2FkZWQgdXNpbmcgdGhlIGxpbmsgYmVsb3cuCgpgYGB7ciBQcm90ZWluX2Fubm90YXRpb25zLCBmaWcuY2FwID0gIkFubm90YXRpb25zIGZvciBhbGwgcHJvdGVpbnMgaW4gb3VyIGRhdGEgc2V0LiJ9CgpsaXN0KGFsbC5wcm90cykgJT4lIAogIGRvd25sb2FkdGhpczo6ZG93bmxvYWRfdGhpcygKICAgIG91dHB1dF9uYW1lID0gIlByb3RlaW4gYW5ub3RhdGlvbnMiLAogICAgb3V0cHV0X2V4dGVuc2lvbiA9ICIueGxzeCIsCiAgICBidXR0b25fbGFiZWwgPSAiRG93bmxvYWQgcHJvdGVpbiBhbm5vdGF0aW9ucyBhcyB4bHN4IiwKICAgIGJ1dHRvbl90eXBlID0gInByaW1hcnkiLAogICAgaGFzX2ljb24gPSBUUlVFLAogICAgaWNvbiA9ICJmYSBmYS1zYXZlIgogICkKCmBgYAoKPGJyPiAKPGJyPgoKIyMjIEZpZ3VyZSAxQjogRGV0ZWN0aW9uIGJpYXMgaW4gcHJvdGVvbWljcwoKYGBge3IgRmlndXJlMUJfcHJlcH0KCiMgZ2V0IHRoZSBsaXN0IG9mIHByb3RlaW4gY29kaW5nIGdlbmVzIHdpdGggdHJhbnNjcmlwdCBhYnVuZGFuY2UgaW4gRE8gbUVTQ3MKYWxsLnByb3RfY29kaW5nLmdlbmVzIDwtICBhbGwuZ2VuZXMgJT4lIAogIGZpbHRlciggZ2VuZV9iaW90eXBlID09InByb3RlaW5fY29kaW5nIikKCiMgZ2V0IGF2ZXJhZ2UgdHJhbnNjcmlwdCBhYnVuZGFuY2UgZm9yIGFsbCBwcm90ZWluIGNvZGluZyBnZW5lcwptcm5hIDwtIGV4cHIuZXNjX3JuYSAlPiUKICBhc190aWJibGUoIHJvd25hbWVzID0gInNhbXBsZWlkIikgJT4lCiAgc2VsZWN0KCBhbGwucHJvdF9jb2RpbmcuZ2VuZXMkZW5zZW1ibF9nZW5lX2lkKSAlPiUgCiAgc3VtbWFyaXplX2FsbCguZnVucyA9IG1lYW4sIG5hLnJtID0gVCkgJT4lIAogIHBpdm90X2xvbmdlciggYWxsLnByb3RfY29kaW5nLmdlbmVzJGVuc2VtYmxfZ2VuZV9pZCwgCiAgICAgICAgICAgICAgICBuYW1lc190byA9ICJlbnNlbWJsX2dlbmVfaWQiLCAKICAgICAgICAgICAgICAgIHZhbHVlc190byA9ICJhdmdfcm5hIikKCiMgYW5ub3RhdGUgaWYgdGhlIGdlbmUgaXMgZm91bmQgaW4gdGhlIHByb3RlaW4gZGF0YSBieSBzZXR0aW5nIHByb3QgPSBUUlVFL0ZBTFNFCiMgYWRkIGF2ZXJhZ2UgdHJhbnNjcmlwdCBhYnVuZGFuY2UgCmFsbC5wcm90X2NvZGluZy5nZW5lcyU+JSAKICBzZWxlY3QoZW5zZW1ibF9nZW5lX2lkLCBtZ2lfc3ltYm9sLGVuc2VtYmxfZ2VuZV9pZCkgJT4lCiAgbXV0YXRlKHByb3QgPSBpZmVsc2UoIChlbnNlbWJsX2dlbmVfaWQgJWluJSBhbGwucHJvdHMkZW5zZW1ibF9nZW5lX2lkIHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgbWdpX3N5bWJvbCAlaW4lIGFsbC5wcm90cyRtZ2lfc3ltYm9sKSwgVFJVRSwgRkFMU0UpKSAlPiUKICBsZWZ0X2pvaW4oLiwgbXJuYSkgLT4gcHJvcC5kYXRhCgoKICAKICAKIyBjYWxjdWxhdGUgdGhlIHByb2JhYmlsaXR5IG9mIGEgcHJvdGVpbiBiZWluZyBwcmVzZW50IGdpdmVuIGl0cyBtUk5BIGFidW5kYW5jZQpnZXRfcHJvcHMgPC0gZnVuY3Rpb24oZGF0KSB7CiAgcHJvcC50YWJsZSA8LSBjKCkKICBmb3IgKGkgaW4gYygxLCA1LCAxMCwgMjUsIDUwLCA3NSwgMTAwLCAxNTAsIDIwMCwgMjUwLCAzMDAsIDQwMCwgNTAwLCA2MDAsIDcwMCwgODAwLCA4MDAsIDEwMDAsIDIwMDAsIDUwMDAsIDEwMDAwLCA1MDAwMCwgMWUwNSkpIHsKICAgIHByb3AgPC0gZGF0ICU+JQogICAgICBtdXRhdGUobVJOQSA9IGlmZWxzZShhdmdfcm5hID4gaSwgImF0IGxlYXN0IiwgImxlc3MgdGhhbiIpKSAlPiUKICAgICAgY291bnQobVJOQSwgcHJvdCkgJT4lCiAgICAgIHNwcmVhZChwcm90LCBuKSAlPiUKICAgICAgbXV0YXRlKCBgRkFMU0VgID0gaWZlbHNlKCBpcy5uYShgRkFMU0VgKSwgMCwgYEZBTFNFYCksCiAgICAgICAgICAgICAgYFRSVUVgID0gaWZlbHNlKCBpcy5uYShgVFJVRWApLCAwLCBgVFJVRWApKSAlPiUgIyByZXBsYWNlIE5BcyBpbiBjYXNlIHRoZXJlIGFyZW4ndCBhbnkgZGV0ZWN0ZWQvdW5kZXRlY3RlZCBwcm90ZWlucwogICAgICBmaWx0ZXIoIChgVFJVRWArYEZBTFNFYCA+IDUpKSAlPiUgIyBmaWx0ZXIgdG8gbWFrZSBzdXJlIGVhY2ggYmluIGhhcyBhdCBsZWFzdCA1IGdlbmVzLiAKICAgICAgbXV0YXRlKGRldGVjdGlvbl9wcm9iYWJpbGl0eSA9IGBUUlVFYCAvIChgRkFMU0VgICsgYFRSVUVgKSkKICAgIHByb3AudGVtcCA8LSBwcm9wICU+JQogICAgICBmaWx0ZXIobVJOQSA9PSAiYXQgbGVhc3QiKSAlPiUKICAgICAgc2VsZWN0KGRldGVjdGlvbl9wcm9iYWJpbGl0eSkgJT4lCiAgICAgIG11dGF0ZShhdmdfcm5hID0gaSkKICAgIHByb3AudGFibGUgPC0gcmJpbmQocHJvcC50YWJsZSwgcHJvcC50ZW1wKQogIH0KICByZXR1cm4ocHJvcC50YWJsZSkKfQoKRmlndXJlMWJfZGF0YSA8LSBnZXRfcHJvcHMocHJvcC5kYXRhKSAlPiUgCiAgcmVuYW1lKCBgUHJvYmFiaWxpdHkgb2YgcHJvdGVpbiBkZXRlY3Rpb25gID0gZGV0ZWN0aW9uX3Byb2JhYmlsaXR5LAogICAgICAgICAgYEF2ZXJhZ2UgdHJhbnNjcmlwdCBhYnVuZGFuY2VgID0gYXZnX3JuYSkKYGBgCgoKYGBge3IgRmlndXJlMUJfcGxvdCwgZmlnLmhlaWdodD00LCBmaWcud2lkdGg9NSwgZmlnLmNhcD0iRmlndXJlIDFCOiBQcm90ZWluIGRldGVjdGlvbiByYXRlIGlzIGxpbmtlZCB0byB0cmFuc2NyaXB0IGFidW5kYW5jZS4gVGhlIHByb2JhYmlsaXR5IG9mIGEgZ2VuZSB0byBoYXZlIHByb3RlaW4gYWJ1bmRhbmNlIG1lYXN1cmVtZW50IGdpdmVuIGl0cyBhdmVyYWdlIHRyYW5zY3JpcHQgYWJ1bmRhbmNlIGFtb25nIDE3NCBtRVNDcyB3aXRoIGJvdGggdHJhbnNjcmlwdG9tZSBhbmQgcHJvdGVvbWUgZGF0YS4ifQoKcHJvYl9wbG90IDwtIEZpZ3VyZTFiX2RhdGEgJT4lIAogIGdncGxvdCgpICsKICBhZXMoeCA9IGBBdmVyYWdlIHRyYW5zY3JpcHQgYWJ1bmRhbmNlYCwgCiAgICAgIHkgPSBgUHJvYmFiaWxpdHkgb2YgcHJvdGVpbiBkZXRlY3Rpb25gKSArCiAgZ2VvbV9wb2ludChzaXplID0gNCkgKwogIHNjYWxlX3hfbG9nMTAoIGV4cGFuZD0gZXhwYW5zaW9uKCBtdWx0ID0gYyguMSwgLjEyKSkpICsKICB0aGVtZV9wdWJjbGVhbihiYXNlX3NpemUgPSAxMikgKwogIGdlb21fbGluZSgpICsKICB5bGFiKCJQcm9iYWJpbGl0eSBvZiBwcm90ZWluIGRldGVjdGlvbiIpICsKICB4bGFiKCJBdmVyYWdlIHRyYW5zY3JpcHQgYWJ1bmRhbmNlIikgKwogIHlsaW0oMC41LCAuOTUpKwogIHRoZW1lKAogICAgYXhpcy50ZXh0ID0gZWxlbWVudF90ZXh0KCBzaXplID0gMTIpLAogICAgYXhpcy50aXRsZSA9IGVsZW1lbnRfdGV4dCggc2l6ZSA9IDEyKQogICkKCmdnYXJyYW5nZShwcm9iX3Bsb3QsIAogICAgICAgICAgbGFiZWxzID0gIkIiLCAKICAgICAgICAgIGZvbnQubGFiZWwgPSBsaXN0KCBzaXplID0gMjApKQoKYGBgCgo8YnI+CgpgYGB7ciBGaWd1cmUxQl9kYXRhLCBmaWcuY2FwPSJEYXRhIHVzZWQgaW4gRmlndXJlIDFCLiJ9CgpGaWd1cmUxYl9kYXRhICU+JSAKICBtdXRhdGVfaWYoIGlzLm51bWVyaWMsIHJvdW5kICwyKSAlPiUgCiAgY3JlYXRlX2R0KCkKCmBgYAoKPGJyPgoKIyMjIyBUYWJsZSBTMi4gT3Zlci1yZXByZXNlbnRhdGlvbiBhbmFseXNpcyBvZiBkZXRlY3RlZCBhbmQgdW5kZXRlY3RlZCBwcm90ZWlucy4gCgpPdmVyLXJlcHJlc2VudGVkIGJpb2xvZ2ljYWwgcHJvY2Vzc2VzIGFuZCBwYXRod2F5cyBpbiBwcm90ZWlucyBkZXRlY3RlZCBpbiBhbGwgc2FtcGxlcywgYW5kIHByb3RlaW4gY29kaW5nIGdlbmVzIHdpdGggdHJhbnNjcmlwdCBhYnVuZGFuY2UgbGFja2luZyBwcm90ZWluIGFidW5kYW5jZSAodW5kZXRlY3RlZCBwcm90ZWlucykgYXJlIGxpc3RlZC4gRGV0YWlscyBpbmNsdWRlIHRoZSBkYXRhIHNvdXJjZSwgdGVybSBpZCwgdGVybSBuYW1lLCB0ZXJtIHNpemUsIHRoZSBudW1iZXIgb2YgaW50ZXJzZWN0aW5nIHByb3RlaW5zIGFuZCB0aGUgRkRSIGZvciBlYWNoIHRlcm0gaWRlbnRpZmllZCB0byBiZSBvdmVycmVwcmVzZW50ZWQgaW4gZGV0ZWN0ZWQgb3IgdW5kZXRlY3RlZCBwcm90ZWluIGNvZGluZyBnZW5lcy4KCmBgYHtyIFRhYmxlUzJfZ2VuZXJhdGUsIGNhY2hlID0gVFJVRSwgd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0KCiMgZ2V0IHByb3RlaW5zIGV4cHJlc3NlZCBpbiBhbGwgc2FtcGxlcwpleHByLmVzY19wcm90LmNvbXAgPC0gZXhwci5lc2NfcHJvdCAlPiUKICBhcy5kYXRhLmZyYW1lKCkgJT4lCiAgc2VsZWN0KCBhbGxfb2YoYWxsLnByb3RzJHByb3RlaW5faWQpKSAgJT4lIAogIHNlbGVjdF9pZih+ICFhbnkoaXMubmEoLikpKQoKIyBnZXQgdGhlIGdlbmUvcHJvdGVpbiBkZXRhaWxzIGZvciBwcm90ZWlucyBtZWFzdXJlZCBpbiBBTEwgdGhlIHNhbXBsZXMKcHJvdHMuZGV0ZWN0ZWQgPC0gYWxsLnByb3RzICU+JSAKICBmaWx0ZXIocHJvdGVpbl9pZCAlaW4lIGNvbG5hbWVzKGV4cHIuZXNjX3Byb3QuY29tcCksCiAgICAgICAgIGdlbmVfYmlvdHlwZT09ICJwcm90ZWluX2NvZGluZyIpCgojIG92ZXItcmVwcmVzZW50YXRpb24gYW5hbHlzaXMgZm9yIHByb3RlaW5zIGRldGVjdGVkIGluIGFsbCBzYW1wbGVzIHZzIGFsbCBwcm90ZWlucwpnLnByb3QuZGV0ZWN0ZWQgPC0gZ29zdCgKICBxdWVyeSA9IHByb3RzLmRldGVjdGVkJG1naV9zeW1ib2wsCiAgb3JnYW5pc20gPSAibW11c2N1bHVzIiwKICBkb21haW5fc2NvcGUgPSAiY3VzdG9tIiwKICBjdXN0b21fYmcgPSBhbGwucHJvdHMkbWdpX3N5bWJvbCwKICBldmNvZGVzID0gVFJVRSwKICBjb3JyZWN0aW9uX21ldGhvZCA9ICJmZHIiCikKZy5wcm90LmRldGVjdGVkJHJlc3VsdCA8LSBnLnByb3QuZGV0ZWN0ZWQkcmVzdWx0ICU+JSAKICBmaWx0ZXIodGVybV9zaXplIDwgNjAwKQoKZy5wcm90LmRldGVjdGVkJHJlc3VsdCAlPiUgCiAgc2VsZWN0KAogICAgYERhdGEgc291cmNlYCA9IHNvdXJjZSwKICAgIGBUZXJtIElEYCA9IHRlcm1faWQsCiAgICBgVGVybSBOYW1lYCA9IHRlcm1fbmFtZSwgCiAgICBgVGVybSBzaXplYCA9IHRlcm1fc2l6ZSwgCiAgICBgIyBvZiBpbnRlcnNlY3RpbmcgcHJvdGVpbnNgID0gaW50ZXJzZWN0aW9uX3NpemUsCiAgICAgRkRSID0gcF92YWx1ZQogICAgKSAtPiB0YWJsZXMyX3NoZWV0MQoKIyBnZXQgcHJvdGVpbnMgbm90IGRldGVjdGVkIGFsdGhvdWdoIFJOQSBpcyBkZXRlY3RlZAphbGwuZ2VuZXMgJT4lIAogIGZpbHRlciggIWVuc2VtYmxfZ2VuZV9pZCAlaW4lIGFsbC5wcm90cyRlbnNlbWJsX2dlbmVfaWQgJiAjIG5vdCBpbiBwcm90ZWluIGRhdGEKICAgICAgICAgICAgZ2VuZV9iaW90eXBlID09ICJwcm90ZWluX2NvZGluZyIpIC0+IG5vdC5kZXRlY3RlZCAKCmFsbC5wcm90X2NvZGluZy5nZW5lcyA8LSAgYWxsLmdlbmVzICU+JSAKICBmaWx0ZXIoIGdlbmVfYmlvdHlwZSA9PSJwcm90ZWluX2NvZGluZyIpCgpnLnByb3Qubm90LmRldGVjdGVkIDwtIGdvc3QoCiAgcXVlcnkgPSBub3QuZGV0ZWN0ZWQkbWdpX3N5bWJvbCwKICBvcmdhbmlzbSA9ICJtbXVzY3VsdXMiLAogIGRvbWFpbl9zY29wZSA9ICJjdXN0b20iLAogIGN1c3RvbV9iZyA9IGFsbC5wcm90X2NvZGluZy5nZW5lcyRtZ2lfc3ltYm9sLCAKICBldmNvZGVzID0gVFJVRSwKICBjb3JyZWN0aW9uX21ldGhvZCA9ICJmZHIiCikKZy5wcm90Lm5vdC5kZXRlY3RlZCRyZXN1bHQgPC0gZy5wcm90Lm5vdC5kZXRlY3RlZCRyZXN1bHQgJT4lIGZpbHRlcih0ZXJtX3NpemUgPCA2MDApCgpnLnByb3Qubm90LmRldGVjdGVkJHJlc3VsdCAlPiUgCiAgc2VsZWN0KAogICAgYERhdGEgc291cmNlYCA9IHNvdXJjZSwKICAgIGBUZXJtIElEYCA9IHRlcm1faWQsCiAgICBgVGVybSBOYW1lYCA9IHRlcm1fbmFtZSwgCiAgICBgVGVybSBzaXplYCA9IHRlcm1fc2l6ZSwgCiAgICBgIyBvZiBpbnRlcnNlY3RpbmcgcHJvdGVpbnNgID0gaW50ZXJzZWN0aW9uX3NpemUsCiAgICAgRkRSID0gcF92YWx1ZQogICAgKSAtPiB0YWJsZXMyX3NoZWV0MgogIApgYGAKCjxicj4KCmBgYHtyIFRhYmxlUzJfZGlzcGxheSwgZWNobyA9IEZBTFNFfQoKCiMgd3JpdGV4bDo6d3JpdGVfeGxzeCggbGlzdCggRGV0ZWN0ZWRfcHJvdGVpbl9jb2RpbmdfZ2VuZXMgPSB0YWJsZXMyX3NoZWV0MSwKIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVuZGV0ZWN0ZWRfcHJvdGVpbl9jb2RpbmdfZ2VuZXMgPSB0YWJsZXMyX3NoZWV0MiksCiMgICAgICAgICAgICAgICAgICAgICBwYXRoID0gaGVyZSgiVGFibGVTMl9PUkFfcHJvdGVpbl9kZXRlY3Rpb24ueGxzeCIpLAojICAgICAgICAgICAgICAgICAgICAgY29sX25hbWVzID0gVFJVRSwKIyAgICAgICAgICAgICAgICAgICAgIGZvcm1hdF9oZWFkZXJzID0gVFJVRQojICAgICAgICAgICAgICAgICAgICAgKQoKCiMgeGZ1bjo6ZW1iZWRfZmlsZShoZXJlKCJUYWJsZV9TMi54bHN4IikpCgpkb3dubG9hZF9maWxlKAogIHBhdGggPSBoZXJlKCJUYWJsZV9TMi54bHN4IiksCiAgb3V0cHV0X25hbWUgPSAiVGFibGVfUzIiLAogIGJ1dHRvbl9sYWJlbCA9ICJEb3dubG9hZCBUYWJsZV9TMi54bHN4IiwKICBidXR0b25fdHlwZSA9ICJwcmltYXJ5IiwKICBoYXNfaWNvbiA9IFRSVUUsCiAgaWNvbiA9ICJmYSBmYS1zYXZlIiwKICBzZWxmX2NvbnRhaW5lZCA9IEZBTFNFCikKCmBgYAoKCjxicj4KCiMjIyMgRmlndXJlIFMxQS1DOiBUcmFuc2NyaXB0aW9uIGZhY3RvcnMgc2hvdyBsb3dlciB0cmFuc2NyaXB0IGFuZCBwcm90ZWluIGFidW5kYW5jZSB0aGFuIG90aGVyIGdlbmVzCgpgYGB7ciBGaWd1cmVTMUFfQywgZmlnLmNhcD0iRmlndXJlUzE6IChBKSBHZW5lcyB3aGVyZSBwcm90ZWluIGFidW5kYW5jZSBpcyBkZXRlY3RlZCBoYXZlIGEgc2lnbmlmaWNhbnRseSBoaWdoZXIgbWVhbiB0cmFuc2NyaXB0IGFidW5kYW5jZSAoT25lIHdheSBBTk9WQSwgZm9sbG93ZWQgYnkgdC10ZXN0KS4gQXZlcmFnZSB0cmFuc2NyaXB0IGFidW5kYW5jZSBvZiBwcm90ZWluIGNvZGluZyBnZW5lcyAobiA9IDEyLDczMikgdGhhdCBhcmUgZGV0ZWN0ZWQgKFRSVUUsIG4gPSA3LDI0MCkgYW5kIG5vdCBkZXRlY3RlZCAoRkFMU0UsIG4gPSA1LDQ5MikgaW4gdGhlIHByb3Rlb21pY3MgZGF0YSBhcmUgcGxvdHRlZC4gKEIsIEMpIFRGcyBzaG93IGEgc2lnbmlmaWNhbnRseSBsb3dlciBtZWFuIGZvciBib3RoIHRyYW5zY3JpcHQgYW5kIHByb3RlaW4gYWJ1bmRhbmNlIGluIGNvbXBhcmlzb24gdG8gb3RoZXIgZ2VuZXMgKE9uZSB3YXkgQU5PVkEsIGZvbGxvd2VkIGJ5IHQtdGVzdCkuIEF2ZXJhZ2UgdHJhbnNjcmlwdCBhbmQgcHJvdGVpbiBhYnVuZGFuY2Ugb2YgcHJvdGVpbiBjb2RpbmcgZ2VuZXMgdGhhdCBhcmUgdHJhbnNjcmlwdGlvbiBmYWN0b3JzIChURikgYW5kIG5vdCB0cmFuc2NyaXB0aW9uIGZhY3RvcnMgKE5vdCBhIFRGKSBhcmUgcGxvdHRlZC4iLCBmaWcud2lkdGg9MTIsIGZpZy5oZWlnaHQ9NX0KCgpybmFfZGV0ZWN0X3Bsb3QgPC0gYXBwbHkobmEub21pdChleHByLmVzY19ybmEpLCAyLCBtZWFuKSAlPiUKICBhcy5kYXRhLmZyYW1lKCkgJT4lCiAgcm93bmFtZXNfdG9fY29sdW1uKCkgJT4lCiAgbGVmdF9qb2luKC4sIGFsbC5nZW5lcywgYnkgPSBjKCJyb3duYW1lIiA9ICJlbnNlbWJsX2dlbmVfaWQiKSkgJT4lCiAgZmlsdGVyKGdlbmVfYmlvdHlwZSAlaW4lIGMoInByb3RlaW5fY29kaW5nIikpICU+JQogIG11dGF0ZShkZXRlY3RlZCA9IGlmZWxzZShyb3duYW1lICVpbiUgYWxsLnByb3RzJGVuc2VtYmxfZ2VuZV9pZCwgIkRldGVjdGVkIiwgIk5vdCBkZXRlY3RlZCIpKSAlPiUKICBnZ3Bsb3QoKSArCiAgYWVzKHggPSBkZXRlY3RlZCwgeSA9IGAuYCkgKwogIGdlb21fYm94cGxvdCh3aWR0aCA9IDAuMikgKwogIHlsYWIoIkF2ZXJhZ2UgdHJhbnNjcmlwdCBhYnVuZGFuY2UiKSArCiAgc2NhbGVfeV9sb2cxMCggZXhwYW5kID0gZXhwYW5zaW9uKG11bHQgPWMoMC40LDAuMikpKSArCiAgdGhlbWVfcHViY2xlYW4oYmFzZV9zaXplID0gMTgpICsKICAjZ2d0aXRsZSgiUHJvdGVpbiBjb2RpbmcgZ2VuZXMiKSArCiAgeGxhYigiIikgKwogIHN0YXRfY29tcGFyZV9tZWFucyhtZXRob2QgPSAiYW5vdmEiLGxhYmVsLnk9Ny41KSsKICBzdGF0X2NvbXBhcmVfbWVhbnMobWV0aG9kID0gInQudGVzdCIsbGFiZWwueT02LjUpCiAgCgp0Zl9ybmFfcGxvdCA8LSBhcHBseShuYS5vbWl0KGV4cHIuZXNjX3JuYSksIDIsIG1lYW4pICU+JQogIGFzLmRhdGEuZnJhbWUoKSAlPiUKICByb3duYW1lc190b19jb2x1bW4oKSAlPiUKICBsZWZ0X2pvaW4oLiwgYWxsLmdlbmVzLCBieSA9IGMoInJvd25hbWUiID0gImVuc2VtYmxfZ2VuZV9pZCIpKSAlPiUKICAgIGZpbHRlcihnZW5lX2Jpb3R5cGUgJWluJSBjKCJwcm90ZWluX2NvZGluZyIpKSAlPiUKICBtdXRhdGUoaXNfdGYgPSBpZmVsc2UoIG1naV9zeW1ib2wgJWluJSBhbGwudGZzJG1naV9zeW1ib2wsICJURiIsICJOb3QgYSBURiIpKSAlPiUKICBnZ3Bsb3QoKSArCiAgYWVzKHggPSBpc190ZiwgeSA9IGAuYCkgKwogIGdlb21fYm94cGxvdCh3aWR0aCA9IDAuMikgKwogIHlsYWIoIkF2ZXJhZ2UgdHJhbnNjcmlwdCBhYnVuZGFuY2UiKSArCiAgc2NhbGVfeV9sb2cxMCggZXhwYW5kID0gZXhwYW5zaW9uKG11bHQgPWMoMC40LDAuMikpKSArCiAgdGhlbWVfcHViY2xlYW4oYmFzZV9zaXplID0gMTgpICsKICAjZ2d0aXRsZSgiUHJvdGVpbiBjb2RpbmcgZ2VuZXMiKSArCiAgeGxhYigiIikgKwogIHN0YXRfY29tcGFyZV9tZWFucyhtZXRob2QgPSAiYW5vdmEiLGxhYmVsLnk9Ny41KSsKICBzdGF0X2NvbXBhcmVfbWVhbnMobWV0aG9kID0gInQudGVzdCIsbGFiZWwueT02LjUpCgp0Zl9wcm90X3Bsb3QgPC0gYXBwbHkoKGV4cHIuZXNjX3Byb3RbLGFsbC5wcm90cyRwcm90ZWluX2lkXSksIDIsIG1lYW4sIG5hLnJtPVRSVUUpICU+JQogIGFzLmRhdGEuZnJhbWUoKSAlPiUKICByb3duYW1lc190b19jb2x1bW4oKSAlPiUKICBsZWZ0X2pvaW4oIC4sIGFsbC5wcm90cywgYnkgPSBjKCJyb3duYW1lIiA9ICJwcm90ZWluX2lkIikpICU+JSAKICBtdXRhdGUoaXNfdGYgPSBpZmVsc2UoIG1naV9zeW1ib2wgJWluJSBhbGwudGZzJG1naV9zeW1ib2wsICJURiIsICJOb3QgYSBURiIpKSAlPiUKICBnZ3Bsb3QoKSArCiAgYWVzKHggPSBpc190ZiwgeSA9IGAuYCkgKwogIGdlb21fYm94cGxvdCh3aWR0aCA9IDAuMikgKwogIHlsYWIoIkF2ZXJhZ2UgcHJvdGVpbiBhYnVuZGFuY2UiKSArCiAgdGhlbWVfcHViY2xlYW4oYmFzZV9zaXplID0gMTgpICsKICAjZ2d0aXRsZSgiUHJvdGVpbiBjb2RpbmcgZ2VuZXMiKSArCiAgeGxhYigiIikgKwogIHNjYWxlX3lfY29udGludW91cyggZXhwYW5kID1leHBhbnNpb24obXVsdCA9YygwLjMsMC4yKSkpICsKICBzdGF0X2NvbXBhcmVfbWVhbnMobWV0aG9kID0gImFub3ZhIiwgbGFiZWwueT0xNykrCiAgc3RhdF9jb21wYXJlX21lYW5zKG1ldGhvZCA9ICJ0LnRlc3QiLGxhYmVsLnk9MTUuNSkKCgoKZGV0ZWN0aW9uX3Bsb3QgPC0gZ2dhcnJhbmdlKHJuYV9kZXRlY3RfcGxvdCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0Zl9ybmFfcGxvdCx0Zl9wcm90X3Bsb3QsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbnJvdyA9IDEsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGhzID0gYygwLjcsMC43LDAuNyksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWxzID0gYygiQSIsIkIiLCJDIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb250LmxhYmVsID0gbGlzdCggc2l6ZSA9IDIwKSkKCmRldGVjdGlvbl9wbG90CgpgYGAKCjxicj4gPGJyPgoKIyMjIEZpZ3VyZSAxQzogUHJpbmNpcGFsIGNvbXBvbmVudCBhbmFseXNpcyBvZiB0aGUgcGx1cmlwb3RlbnQgcHJvdGVvbWUKCmBgYHtyIEZpZ3VyZTFDX3ByZXB9CgojIHByaW5jaXBhbCBjb21wb25lbnQgYW5hbHlzaXMgdXNpbmcgcGNhTWV0aG9kczo6cGNhIGZ1bmN0aW9uLgpwY2EucHJvdCA8LSBwY2Eob2JqZWN0ID0gZXhwci5lc2NfcHJvdCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXRob2QgPSAic3ZkSW1wdXRlIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY2FsZSA9ICJ1diIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgblBjcyA9IDEwLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNlbnRlciA9IFRSVUUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICkKCiMgZ2V0IHZhbHVlcyBmb3IgUHJpbmNpcGFsIGNvbXBvbmVudHMKRmlndXJlMWNfZGF0YSA8LSBzY29yZXMocGNhLnByb3QpICU+JQogIGFzX3RpYmJsZSggcm93bmFtZXMgPSJzYW1wbGVpZCIpICU+JSAKICBsZWZ0X2pvaW4oY292YXJUaWR5LmVzY19wcm90KSAlPiUKICBtdXRhdGUoc2V4ID0gaWZlbHNlKHNleCA9PSAiRiIsICJGZW1hbGUiLCAiTWFsZSIpKSAlPiUKICByZW5hbWUoCiAgICBgU2FtcGxlIElEYCA9IHNhbXBsZWlkLCAKICAgIFNleCA9IHNleAogICkgCgpgYGAKCmBgYHtyIEZpZ3VyZTFDX3Bsb3QsIGZpZy5jYXA9IkZpZ3VyZSAxQzogUHJpbmNpcGFsIGNvbXBvbmVudCBhbmFseXNpcyByZXZlYWxzIHNleCBhcyBhIHNpZ25pZmljYW50IHNvdXJjZSBvZiB2YXJpYXRpb24gYW1vbmcgRE8gbUVTQyBwcm90ZW9tZXMuIFBDMSBhbmQgUEMyIGZvciAxOTAgbUVTQ3MgYXJlIHBsb3R0ZWQgYW5kIGNvbG9yZWQgYnkgc2V4LiIsIGZpZy53aWR0aD04LCBmaWcuaGVpZ2h0PTR9CgoKRmlndXJlMWNfZGF0YSAlPiUgCiAgZ2dwbG90KCkgKwogIGFlcyh4ID0gUEMxLCB5ID0gUEMyLCBjb2wgPSBTZXgpICsKICBnZW9tX3BvaW50KHNpemUgPSA0LCBhbHBoYSA9IDAuNykgKwogIHRoZW1lKAogICAgYXhpcy50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxOCksCiAgICBheGlzLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAyMCksIAogICAgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE2KSwgbGVnZW5kLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNikKICApICsKICB4bGFiKHBhc3RlMCgiUEMxICgiLCByb3VuZChwY2EucHJvdEBSMlsxXSwgMykgKiAxMDAsICIlKSIpKSArCiAgeWxhYihwYXN0ZTAoIlBDMiAoIiwgcm91bmQocGNhLnByb3RAUjJbMl0sIDMpICogMTAwLCAiJSkiKSkgKwogIHRoZW1lX3B1YmNsZWFuKGJhc2Vfc2l6ZSA9IDE4KSArIAogIGNvbG9yX3BhbGV0dGUoIm5wZyIpKwogIGZpbGxfcGFsZXR0ZSgibnBnIikrCiAgeGxpbSgtMTAwLDE1MCkrCiAgeWxpbSgtMTAwLDE1MCkrCiAgZmFjZXRfd3JhcCh+U2V4LCBzdHJpcC5wb3NpdGlvbiA9ICJyaWdodCIpKwogIHRoZW1lKAogICAgc3RyaXAuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgIHN0cmlwLnRleHQueCA9IGVsZW1lbnRfYmxhbmsoKQogICkgLT4gcGNhX3Bsb3QKCmdnYXJyYW5nZShwY2FfcGxvdCwgCiAgICAgICAgICBsYWJlbHMgPSAiQyIsCiAgICAgICAgICBmb250LmxhYmVsID0gbGlzdCggc2l6ZSA9IDIwKSkKCgoKYGBgCgo8YnI+CgpUaGUgZGF0YSB1c2VkIGluIHBsb3R0aW5nIEZpZ3VyZTFDIGNhbiBiZSBkb3dubG9hZGVkIHVzaW5nIHRoZSBsaW5rIGJlbG93LgoKYGBge3IgRmlndXJlMUNfZGF0YSwgZmlnLmNhcD0iRGF0YSB1c2VkIGluIHBsb3R0aW5nIEZpZ3VyZSAxQy4ifQoKbGlzdCggRmlndXJlMWNfZGF0YSAlPiUgCiAgICAgICAgc2VsZWN0KGBTYW1wbGUgSURgLCBTZXgsIFBDMSwgUEMyKSkgJT4lIAogIGRvd25sb2FkdGhpczo6ZG93bmxvYWRfdGhpcygKICAgIG91dHB1dF9uYW1lID0gIkZpZ3VyZTFDIGRhdGEiLAogICAgb3V0cHV0X2V4dGVuc2lvbiA9ICIueGxzeCIsCiAgICBidXR0b25fbGFiZWwgPSAiRG93bmxvYWQgRmlndXJlMUMgZGF0YSBhcyB4bHN4IiwKICAgIGJ1dHRvbl90eXBlID0gInByaW1hcnkiLAogICAgaGFzX2ljb24gPSBUUlVFLAogICAgaWNvbiA9ICJmYSBmYS1zYXZlIgogICkKCmBgYAoKPGJyPgoKIyMjIyBEcml2ZXJzIG9mIFBDMQoKYGBge3IgUEMxX2RyaXZlcnMsIGZpZy53aWR0aD0xMCwgZmlnLmhlaWdodD01LCBmaWcuY2FwPSJDaHJvbW9zb21hbCBsb2NhdGlvbnMgb2YgdGhlIHRvcCAxMCUgb2YgcHJvdGVpbnMgdGhhdCBjb250cmlidXRlIHRvIFBDMS4ifQoKIyBnZXQgdG9wIGRyaXZlcnMgb2YgUEMxCmxvYWRpbmdzKHBjYS5wcm90KSAlPiUKICBhc190aWJibGUoIHJvd25hbWVzID0gInByb3RlaW5faWQiKSAlPiUgCiAgbGVmdF9qb2luKCBhbGwucHJvdHMpICU+JSAKICBzZWxlY3QobWdpX3N5bWJvbCwgZ2VuZV9jaHIsIFBDMSkgJT4lCiAgZmlsdGVyKCBhYnMoUEMxKSA+PSBxdWFudGlsZShhYnMoUEMxKSwgMC45MCkpLT4gcGMxLmxvYWRpbmdzICMgbW9zdCBjb250cmlidXRpbmcgMTAlCgojIFBDMSBkcml2ZXJzIGJ5IGNocm9tb3NvbWUKCnBjMS5sb2FkaW5ncyAlPiUgCiAgZ3JvdXBfYnkoZ2VuZV9jaHIpICU+JQogICMgY291bnQoKSAlPiUKICAjIGFycmFuZ2UoZGVzYyhuKSkgJT4lCiAgZ2dwbG90KCkrCiAgYWVzKCB4ID0gZ2VuZV9jaHIpKwogIGdlb21fYmFyKCkrCiAgdGhlbWVfcHViY2xlYW4oIGJhc2Vfc2l6ZSA9IDE4KSsKICB4bGFiKCJDaHIiKQogIApgYGAKCjxicj4KCmBgYHtyIFBDMV9kcml2ZXJzX09SQSwgZmlnLmNhcD0iT3Zlci1yZXByZXNlbnRlZCBiaW9sb2dpY2FsIHByb2Nlc3NlcyBhbmQgcGF0aHdheXMgaW4gUEMxIGRyaXZlcnMuIiwgY2FjaGUgPSBUUlVFfQoKCgpnLnBjMSA8LSBnb3N0KHF1ZXJ5ID0gcGMxLmxvYWRpbmdzJG1naV9zeW1ib2wsIAogICAgICAgICAgICAgIG9yZ2FuaXNtID0gIm1tdXNjdWx1cyIsIAogICAgICAgICAgICAgIGRvbWFpbl9zY29wZSA9ICJjdXN0b20iLCAKICAgICAgICAgICAgICBjdXN0b21fYmcgPSBhbGwucHJvdHMkbWdpX3N5bWJvbCwgCiAgICAgICAgICAgICAgZXZjb2RlcyA9IFRSVUUsCiAgICAgICAgICAgICAgY29ycmVjdGlvbl9tZXRob2QgPSAiZmRyIikKZy5wYzEkcmVzdWx0IDwtIGcucGMxJHJlc3VsdCAlPiUgZmlsdGVyKHRlcm1fc2l6ZSA8IDYwMCkKCmcucGMxJHJlc3VsdCAlPiUgCiAgIHNlbGVjdCgKICAgIGBEYXRhIHNvdXJjZWAgPSBzb3VyY2UsCiAgICBgVGVybSBJRGAgPSB0ZXJtX2lkLAogICAgYFRlcm0gTmFtZWAgPSB0ZXJtX25hbWUsIAogICAgYFRlcm0gc2l6ZWAgPSB0ZXJtX3NpemUsIAogICAgYCMgb2YgaW50ZXJzZWN0aW5nIHByb3RlaW5zYCA9IGludGVyc2VjdGlvbl9zaXplLAogICAgIEZEUiA9IHBfdmFsdWUKICAgICkgJT4lCiAgbXV0YXRlX2lmKCBpcy5udW1lcmljLCBmb3JtYXRDLCBkaWdpdHMgPTIpICU+JSAKICBjcmVhdGVfZHQoKQoKYGBgCgo8YnI+CgojIyMjIEZpZ3VyZSBTMUQtRTogVmFyaWF0aW9uIGluIHByb3RlaW4gYWJ1bmRhbmNlCgpgYGB7ciBGaWd1cmVTMURfRSwgZmlnLmNhcD0iKEQsIEUpIFByb3RlaW4gYWJ1bmRhbmNlIGlzIGhpZ2hseSB2YXJpYWJsZSBhY3Jvc3MgRE8gbUVTQ3MuIEhpc3RvZ3JhbXMgc2hvd2luZyB0aGUgbWVhbiBhYnVuZGFuY2UgYW5kIHZhcmlhbmNlIHBlciBwcm90ZWluIHBsb3R0ZWQgZm9yIDcsMzQyIHByb3RlaW5zIGFjcm9zcyAxOTAgRE8gbUVTQyBsaW5lcy4iLCBmaWcud2lkdGg9OCwgZmlnLmhlaWdodD00fQoKZXhwci5lc2NfcHJvdCAlPiUKICBhc190aWJibGUoLikgJT4lCiAgc3VtbWFyaXNlX2FsbChsaXN0KH4gbWVhbiguLCBuYS5ybSA9IFQpKSkgJT4lIAogIHBpdm90X2xvbmdlciggYWxsLnByb3RzJHByb3RlaW5faWQsCiAgICAgICAgICAgICAgICBuYW1lc190byA9ICJwcm90ZWluX2lkIiwKICAgICAgICAgICAgICAgIHZhbHVlc190byA9Im1lYW4ucHJvdCIpICU+JSAKICBnZ3Bsb3QoKSArCiAgYWVzKHggPSBtZWFuLnByb3QpICsKICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IDAuMSkgKwogIHhsYWIoIk1lYW4iKSArCiAgdGhlbWVfcHViY2xlYW4oYmFzZV9zaXplID0gMTgpIC0+IHAubWVhbi5oaXN0CgpleHByLmVzY19wcm90ICU+JQogIGFzX3RpYmJsZSguKSAlPiUKICBzdW1tYXJpc2VfYWxsKGxpc3QofiB2YXIoLiwgbmEucm0gPSBUKSkpICU+JSAKICBwaXZvdF9sb25nZXIoIGFsbC5wcm90cyRwcm90ZWluX2lkLAogICAgICAgICAgICAgICAgbmFtZXNfdG8gPSAicHJvdGVpbl9pZCIsCiAgICAgICAgICAgICAgICB2YWx1ZXNfdG8gPSJ2YXIiKSAlPiUgCiAgZ2dwbG90KCkgKwogIGFlcyh4ID0gdmFyKSArCiAgZ2VvbV9oaXN0b2dyYW0oYmlud2lkdGggPSAwLjAxKSArCiAgeGxhYigiVmFyaWFuY2UiKSArCiAgdGhlbWVfcHViY2xlYW4oYmFzZV9zaXplID0gMTgpICsKICBzY2FsZV94X2xvZzEwKCkgLT4gcC52YXIuaGlzdAoKZ2dhcnJhbmdlKHAubWVhbi5oaXN0LCAKICAgICAgICAgIHAudmFyLmhpc3QsIAogICAgICAgICAgbnJvdyA9MSwgCiAgICAgICAgICBsYWJlbHMgPSBjKCJEIiwiRSIpLAogICAgICAgICAgZm9udC5sYWJlbCA9IGxpc3QoIHNpemUgPSAxOCkpCgpgYGAKCjxicj4KCiMjIyMgU2V4IGVmZmVjdHMgb24gcHJvdGVpbiBhYnVuZGFuY2UKCmBgYHtyIHNleF9lZmYsIGNhY2hlID0gVFJVRSwgcmVzdWx0cz0naGlkZSd9CgojIHVwZGF0aW5nIHRoZSBjb2RlIHRvIHVzZSBhbm92YSBmb2xsb3dlZCBieSB0dWtleSdzIGhzZDoKZXhwci5lc2NfcHJvdCAlPiUKICB0KCkgJT4lIAogIGFzX3RpYmJsZShyb3duYW1lcyA9ICJwcm90ZWluX2lkIikgJT4lCiAgZmlsdGVyKCBwcm90ZWluX2lkICVpbiUgYWxsLnByb3RzJHByb3RlaW5faWQpICU+JSAKICBwaXZvdF9sb25nZXIoIGNvbHMgPSByb3duYW1lcyhleHByLmVzY19wcm90KSwKICAgICAgICAgICAgICAgIHZhbHVlc190byA9ICJwcm90ZWluX2FiIiwKICAgICAgICAgICAgICAgIG5hbWVzX3RvID0gInNhbXBsZWlkIikgJT4lIAogIGxlZnRfam9pbiguLCBzZWxlY3QoY292YXJUaWR5LmVzY19wcm90LCBzYW1wbGVpZCwgc2V4KSkgJT4lIAogIGdyb3VwX2J5KHByb3RlaW5faWQpICU+JSAKICByc3RhdGl4Ojphbm92YV90ZXN0KCBwcm90ZWluX2FiIH4gc2V4KSAlPiUgCiAgcnN0YXRpeDo6YWRqdXN0X3B2YWx1ZSggbWV0aG9kID0gIkJIIikgJT4lIAogIHJzdGF0aXg6OmFkZF9zaWduaWZpY2FuY2UoInAuYWRqIikgJT4lIAogIGFzX3RpYmJsZSgpIC0+IHByb3Rfc2V4X2FvdgoKIyBwYXNzaW5nIHRoZSBmdWxsIGRhdGEgdG8gdHVrZXkncyB0aGVuIGZpbHRlcmluZwpleHByLmVzY19wcm90ICU+JQogIHQoKSAlPiUgCiAgYXNfdGliYmxlKHJvd25hbWVzID0gInByb3RlaW5faWQiKSAlPiUgCiAgZmlsdGVyKCBwcm90ZWluX2lkICVpbiUgYWxsLnByb3RzJHByb3RlaW5faWQpICU+JSAKICBwaXZvdF9sb25nZXIoIGNvbHMgPSByb3duYW1lcyhleHByLmVzY19wcm90KSwKICAgICAgICAgICAgICAgIHZhbHVlc190byA9ICJwcm90ZWluX2FiIiwKICAgICAgICAgICAgICAgIG5hbWVzX3RvID0gInNhbXBsZWlkIikgJT4lIAogIGxlZnRfam9pbiguLCBzZWxlY3QoY292YXJUaWR5LmVzY19wcm90LCBzYW1wbGVpZCwgc2V4KSkgJT4lIAogIGdyb3VwX2J5KHByb3RlaW5faWQpICU+JSAKICByc3RhdGl4Ojp0dWtleV9oc2QocHJvdGVpbl9hYiB+IHNleCkgJT4lIAogIGZpbHRlciggcHJvdGVpbl9pZCAlaW4lIChmaWx0ZXIocHJvdF9zZXhfYW92LCBwLmFkai5zaWduaWYgIT0gIm5zIikpJHByb3RlaW5faWQgKSAtPiBwcm90X3NleF90dWtleXMKCgojIGdldCB0aGUgbWVkaWFucyBmb3IgbGF0ZXIKZXhwci5lc2NfcHJvdCAlPiUKICB0KCkgJT4lIAogIGFzX3RpYmJsZShyb3duYW1lcyA9ICJwcm90ZWluX2lkIikgJT4lCiAgZmlsdGVyKCBwcm90ZWluX2lkICVpbiUgYWxsLnByb3RzJHByb3RlaW5faWQpICU+JSAKICBwaXZvdF9sb25nZXIoIGNvbHMgPSByb3duYW1lcyhleHByLmVzY19wcm90KSwKICAgICAgICAgICAgICAgIHZhbHVlc190byA9ICJwcm90ZWluX2FiIiwKICAgICAgICAgICAgICAgIG5hbWVzX3RvID0gInNhbXBsZWlkIikgJT4lIAogIGxlZnRfam9pbiguLCBzZWxlY3QoY292YXJUaWR5LmVzY19wcm90LCBzYW1wbGVpZCwgc2V4KSkgJT4lIAogIGdyb3VwX2J5KHByb3RlaW5faWQsc2V4KSAlPiUgCiAgc3VtbWFyaXplKCBtZWQgPSBtZWRpYW4ocHJvdGVpbl9hYiwgbmEucm0gPVQpKSAlPiUgCiAgcGl2b3Rfd2lkZXIoIGlkX2NvbHMgPSAicHJvdGVpbl9pZCIsCiAgICAgICAgICAgICAgIG5hbWVzX2Zyb20gPSAic2V4IiwKICAgICAgICAgICAgICAgdmFsdWVzX2Zyb20gPSAibWVkIiktPiBwcm90X3NleF9tZWQKYGBgCgpgYGB7ciBTZXhfZWZmX3RhYmxlLCBmaWcuY2FwPSJUYWJsZSBvZiBwcm90ZWlucyBzaG93aW5nIGEgc2lnbmlmaWNhbnQgc2V4IGVmZmVjdC4ifQoKcHJvdF9zZXhfdHVrZXlzICU+JQogIGxlZnRfam9pbiggYWxsLnByb3RzKSAlPiUgCiAgbGVmdF9qb2luKCBwcm90X3NleF9tZWQpICU+JSAKICBhcnJhbmdlKHAuYWRqKSAlPiUKICBtdXRhdGVfaWYoIGlzLm51bWVyaWMsIHJvdW5kLCAyKSAlPiUKICBzZWxlY3QoCiAgICBgUHJvdGVpbiBJRGAgPSBwcm90ZWluX2lkLAogICAgYE1HSSBTeW1ib2xgPSBtZ2lfc3ltYm9sLCAKICAgIGBQcm90ZWluIGxvY2F0aW9uIChjaHIpYCA9IGdlbmVfY2hyLAogICAgYEZlbWFsZSBtZWRpYW5gPWBGYCwKICAgIGBNYWxlIG1lZGlhbmA9IE0KICAgKSAlPiUKICBjcmVhdGVfZHQoKQoKYGBgCgo8YnI+IAo8YnI+CgojIyMgRmlndXJlIDFEOiBHZW5lc2V0IHZhcmlhdGlvbiBhbmFseXNpcyBvZiB0aGUgcGx1cmlwb3RlbnQgcHJvdGVvbWUKCmBgYHtyIHJ1bl9nc3ZhX3Byb3RlaW5fYW5kX3JuYSwgY2FjaGUgPSBUUlVFLCByZXN1bHRzPSdoaWRlJywgd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0KCmxpYnJhcnkoR1NWQSkKbGlicmFyeShHTy5kYikKCiMgUHJlcGFyaW5nIGdlbmUgc2V0cyBmcm9tIEdPCiMgcmVhZGluZyBpbiB0aGUgR08gKyBtZ2kgZG93bmxvYWRlZCBmcm9tOiBodHRwOi8vd3d3LmluZm9ybWF0aWNzLmpheC5vcmcvZ290b29scy9kYXRhL2lucHV0L01HSWdlbmVzX2J5X0dPaWQudHh0CmdvX3Rlcm1zIDwtIHJlYWRfdHN2KCAiaHR0cDovL3d3dy5pbmZvcm1hdGljcy5qYXgub3JnL2dvdG9vbHMvZGF0YS9pbnB1dC9NR0lnZW5lc19ieV9HT2lkLnR4dCIpICU+JSAKICBtdXRhdGUoIGdlbmVzID0gc3RyX3NwbGl0KGdlbmVzLCAiLCIpKSAlPiUgCiAgdW5uZXN0KCkgIyBzZXBhcmV0ZSB0aGUgc3ltYm9scywgbm90ZSB0aGUgb3ZlcmxhcDogbGVuZ3RoKGludGVyc2VjdCh1bmlxdWUoZ29fdGVybXMkZ2VuZXMpLCBhbGwucHJvdHMkbWdpX3N5bWJvbCkgKSA9IDY3NTcKCnNsaW1fZ29fdGVybXMgPC0gcmVhZF90c3YoICJodHRwOi8vd3d3LmluZm9ybWF0aWNzLmpheC5vcmcvZ290b29scy9kYXRhL2lucHV0L21hcDJNR0lzbGltLnR4dCIpICU+JSAKICBzZWxlY3QoLXRlcm0pICU+JSAKICBtdXRhdGUoIE9OVCA9IGNhc2Vfd2hlbiggYXNwZWN0ID09ICJQIiB+ICAiQlAiLAogICAgICAgICAgICAgICAgICAgICBhc3BlY3QgPT0gIkYiIH4gIk1GIiwKICAgICAgICAgICAgICAgICAgICAgYXNwZWN0ID09ICJDIiB+ICJDQyIKICAgICAgICAgICAgICAgICAgICAgKQogICAgICAgICAgKSAlPiUgCiAgc2VsZWN0KC1hc3BlY3QpCgpnZW5lc2J5Z28gPC0gc3BsaXQoZ29fdGVybXMkZ2VuZXMsIGdvX3Rlcm1zJEdPX2lkKQoKZ29fdGVybXNfYW5ub3QgPC0gZ29fdGVybXMgJT4lICAKICBzZWxlY3QoR09faWQpICU+JSAKICBkaXN0aW5jdCgpICU+JSAKICBsZWZ0X2pvaW4oIHNsaW1fZ29fdGVybXMgJT4lICBzZWxlY3QoIEdPX2lkLCBPTlQpICU+JSBkaXN0aW5jdCgpKQoKZ29hbm5vdF93ZGVmIDwtIEFubm90YXRpb25EYmk6OnNlbGVjdChHTy5kYiwga2V5cz0gdW5pcXVlKGdvX3Rlcm1zJEdPX2lkKSwgY29sdW1ucz1jKCJHT0lEIiwiREVGSU5JVElPTiIsIk9OVE9MT0dZIiwiVEVSTSIpKSAlPiUKICBsZWZ0X2pvaW4oIHNsaW1fZ29fdGVybXMsIGJ5PWMoIkdPSUQiPSJHT19pZCIpKSAlPiUgCiAgbXV0YXRlKCBPTlRPTE9HWSA9IE9OVCkgJT4lIAogIHNlbGVjdCgtT05UKQoKZ29fYnAgPC0gZ29hbm5vdF93ZGVmICU+JSBmaWx0ZXIoIE9OVE9MT0dZID09ICJCUCIpICU+JSAKICBzZWxlY3QoR09JRCkgJT4lICBkaXN0aW5jdCgpCgojIFJ1biBHU1ZBIHVzaW5nIHByb3RlaW4gYWJ1bmRhbmNlCmV4cHIuZXNjX3Byb3RfdXBkIDwtIGV4cHIuZXNjX3Byb3RbLCBhbGwucHJvdHMkcHJvdGVpbl9pZF0KY29sbmFtZXMoZXhwci5lc2NfcHJvdF91cGQpIDwtIGFsbC5wcm90cyRtZ2lfc3ltYm9sCmdzdmFfcHJvdCA8LSBnc3ZhKCAgZXhwciA9IHQoZXhwci5lc2NfcHJvdF91cGQpLAogICAgICAgICAgICAgICAgICAgIGdlbmVzYnlnbywKICAgICAgICAgICAgICAgICAgICBtZXRob2QgPSJnc3ZhIiwKICAgICAgICAgICAgICAgICAgICBrY2RmID0gIm5vbmUiLAogICAgICAgICAgICAgICAgICAgIG1pbi5zeiA9IDUsIAogICAgICAgICAgICAgICAgICAgIG1heC5zeiA9IDEwMDAsCiAgICAgICAgICAgICAgICAgICAgbXguZGlmZiA9IFRSVUUpCgojIFJ1biBHU1ZBIHdpdGggY29tcGxleGVzIHRvIGNvbXBsZW1lbnQgdGhlIGNvLWFidW5kYW5jZSBhbmFseXNpcwpnZW5lc19mb3JfY29tcGxleF9nc3ZhIDwtIGNvbXBsZXguZ2VuZXMgJT4lICAKICBlbmZyYW1lKCAiQ29tcGxleCBOYW1lIiwiaHVtYW5faWRzIikgJT4lCiAgdW5uZXN0KGh1bWFuX2lkcykgJT4lIAogIGxlZnRfam9pbiggY29tcGxleC5nZW5lLmxpc3QpICU+JSAKICBmaWx0ZXIoICFpcy5uYShwcm90ZWluX2lkKSkgJT4lIAogIHNlbGVjdCggYENvbXBsZXggTmFtZWAgLCBwcm90ZWluX2lkKQpnc3ZhX2NvbXBsZXhlcyA8LSB1bmlxdWUoZ2VuZXNfZm9yX2NvbXBsZXhfZ3N2YSRgQ29tcGxleCBOYW1lYCkKZ2VuZXNfYnlfY29tcGxleCA8LSBzcGxpdChnZW5lc19mb3JfY29tcGxleF9nc3ZhJHByb3RlaW5faWQsIGdlbmVzX2Zvcl9jb21wbGV4X2dzdmEkYENvbXBsZXggTmFtZWApCmdzdmFfcHJvdF9jb21wIDwtICBnc3ZhKCAgZXhwciA9IHQoZXhwci5lc2NfcHJvdFssYWxsLnByb3RzJHByb3RlaW5faWRdKSwKICAgICAgICAgICAgICAgICAgICBnZW5lc19ieV9jb21wbGV4LAogICAgICAgICAgICAgICAgICAgIG1ldGhvZCA9ImdzdmEiLAogICAgICAgICAgICAgICAgICAgIGtjZGYgPSAibm9uZSIsCiAgICAgICAgICAgICAgICAgICAgbWluLnN6ID0gNSwgCiAgICAgICAgICAgICAgICAgICAgbWF4LnN6ID0gMTAwMCwKICAgICAgICAgICAgICAgICAgICBteC5kaWZmID0gVFJVRSkKCiMgUnVuIEdTVkEgdXNpbmcgdHJhbnNjcmlwdCBhYnVuZGFuY2UKZXhwci5lc2Nfcm5hX3VwZCA8LSBleHByLmVzY19ybmFbLCBhbGwuZ2VuZXMkZW5zZW1ibF9nZW5lX2lkXQpjb2xuYW1lcyhleHByLmVzY19ybmFfdXBkKSA8LSBhbGwuZ2VuZXMkbWdpX3N5bWJvbApnc3ZhX3JuYSA8LSBnc3ZhKCAgZXhwciA9IHQoZXhwci5lc2Nfcm5hX3VwZCksCiAgICAgICAgICAgICAgICAgICAgZ2VuZXNieWdvLAogICAgICAgICAgICAgICAgICAgIG1ldGhvZCA9ImdzdmEiLAogICAgICAgICAgICAgICAgICAgIGtjZGYgPSAibm9uZSIsCiAgICAgICAgICAgICAgICAgICAgbWluLnN6ID0gNSwgCiAgICAgICAgICAgICAgICAgICAgbWF4LnN6ID0gMTAwMCwKICAgICAgICAgICAgICAgICAgICBteC5kaWZmID0gVFJVRSkKCiMgQW5ub3RhdGlvbiBhbmQgc3RhdGlzdGljYWwgZm9sbG93IHVwIHVzaW5nIEFOT1ZBICsgVHVrZXkncyBvbiBQcm90ZWluIHJlc3VsdHMKY292YXIubGlmciAgJT4lIAogIHJlbmFtZSggdG9wX211Z2EgPSByb3duYW1lICkgJT4lIAogIGxlZnRfam9pbihzYW1wbGUubWF0Y2hlcy5hbGwpICU+JSAKICBzZWxlY3Qoc2FtcGxlaWQsIGxpZnJfZ2VubykgJT4lIAogIGlubmVyX2pvaW4oY292YXJUaWR5LmVzY19wcm90KSAtPiBjb3Zhcl9saWZyX3VwZAoKZ3N2YV9wcm90ICU+JSAKICBhc190aWJibGUocm93bmFtZXMgPSAiQ2F0ZWdvcnkiKSAlPiUgCiAgZmlsdGVyKCBDYXRlZ29yeSAlaW4lIGdvX2JwJEdPSUQpICU+JSAjZmlsdGVyaW5nIGZvciBCUAogIHJiaW5kKCBhc190aWJibGUoZ3N2YV9wcm90X2NvbXAsIHJvd25hbWVzID0gIkNhdGVnb3J5IiApKSAlPiUgCiAgIyByYmluZCggYXNfdGliYmxlKGdzdmFfcHJvdDMsIHJvd25hbWVzID0gIkNhdGVnb3J5IiApKSAlPiUgCiAgIyByYmluZCggYXNfdGliYmxlKGdzdmFfcHJvdDQsIHJvd25hbWVzID0gIkNhdGVnb3J5IikpICU+JSAKICBwaXZvdF9sb25nZXIoIGNvbHMgPSByb3duYW1lcyhleHByLmVzY19wcm90X3VwZCksCiAgICAgICAgICAgICAgICB2YWx1ZXNfdG8gPSAiRW5yaWNobWVudF9TY29yZSIsCiAgICAgICAgICAgICAgICBuYW1lc190byA9ICJzYW1wbGVpZCIpICU+JSAKICAjIGFkZCBzZXhlcyArIGxpZnIgZ2Vub3R5cGVzCiAgbGVmdF9qb2luKCBjb3Zhcl9saWZyX3VwZCkgLT4gZ3N2YV9yZXN1bHRzCgoKZ3N2YV9yZXN1bHRzICU+JSAKICBncm91cF9ieSggQ2F0ZWdvcnkpICU+JSAKICByc3RhdGl4Ojphbm92YV90ZXN0KCBFbnJpY2htZW50X1Njb3JlIH4gc2V4K2xpZnJfZ2VubytzZXgqbGlmcl9nZW5vKSAlPiUgCiAgcnN0YXRpeDo6YWRqdXN0X3B2YWx1ZShtZXRob2QgPSAiQkgiKSAlPiUKICByc3RhdGl4OjphZGRfc2lnbmlmaWNhbmNlKCJwLmFkaiIpICU+JSAKICB1bmdyb3VwKCkgLT4gYW92X3Jlc3VsdHMgCgphb3ZfcmVzdWx0cyAlPiUgCiAgYXNfdGliYmxlKCkgJT4lIAogIGZpbHRlciggcC5hZGouc2lnbmlmICE9ICJucyIgKSAtPiBzaWduaWZfZWZmX3Rlcm1zCgojIHBhc3NpbmcgYWxsIHRvIFR1a2V5J3Mgd2l0aCB0aGUgZnVsbCBtb2RlbApnc3ZhX3Jlc3VsdHMgJT4lIAogIGdyb3VwX2J5KENhdGVnb3J5KSAlPiUgCiAgcnN0YXRpeDo6dHVrZXlfaHNkKCBFbnJpY2htZW50X1Njb3JlIH4gc2V4K2xpZnJfZ2VubytzZXg6bGlmcl9nZW5vKSAlPiUgCiAgdW5ncm91cCgpICU+JSAKICBhc190aWJibGUoKSAlPiUgCiAgbGVmdF9qb2luKCBnb2Fubm90X3dkZWYsIGJ5ID0gYygiQ2F0ZWdvcnkiID0gIkdPSUQiKSkgLT4gcmVzdWx0c190dWtleQoKIyBmaWx0ZXJpbmcgZm9yIHRoZSBvbmVzIHRoYXQgd2VyZSBzaWduaWZpY2FudCBpbiBBTk9WQSArIFR1a2V5J3MKcmVzdWx0c190dWtleSAlPiUgCiAgZmlsdGVyKCBwLmFkaiA8IDAuMDUpICU+JSAKICBpbm5lcl9qb2luKCAuLCBzZWxlY3QoIHNpZ25pZl9lZmZfdGVybXMsIENhdGVnb3J5LCB0ZXJtID0gRWZmZWN0KSkgLT4gc2lnbmlmX3Jlc3VsdHNfdHVrZXkKCiMgQW5ub3RhdGlvbiBhbmQgc3RhdGlzdGljYWwgZm9sbG93IHVwIHVzaW5nIEFOT1ZBICsgVHVrZXkncyBvbiBSTkEgcmVzdWx0cwpnc3ZhX3JuYSAlPiUgCiAgYXNfdGliYmxlKHJvd25hbWVzID0gIkNhdGVnb3J5IikgJT4lIAogIGZpbHRlciggQ2F0ZWdvcnkgJWluJSBnb19icCRHT0lEKSAlPiUgI2ZpbHRlcmluZyBmb3IgQlAKICBwaXZvdF9sb25nZXIoIGNvbHMgPSByb3duYW1lcyhleHByLmVzY19ybmFfdXBkKSwKICAgICAgICAgICAgICAgIHZhbHVlc190byA9ICJFbnJpY2htZW50X1Njb3JlIiwKICAgICAgICAgICAgICAgIG5hbWVzX3RvID0gInNhbXBsZWlkIikgJT4lIAogICMgYWRkIHNleGVzICsgbGlmciBnZW5vdHlwZXMKICBsZWZ0X2pvaW4oIGNvdmFyX2xpZnJfdXBkKSAtPiBnc3ZhX3JuYV9yZXN1bHRzCgpnc3ZhX3JuYV9yZXN1bHRzICU+JSAKICBncm91cF9ieSggQ2F0ZWdvcnkpICU+JSAKICByc3RhdGl4Ojphbm92YV90ZXN0KCBFbnJpY2htZW50X1Njb3JlIH4gc2V4K2xpZnJfZ2VubytzZXgqbGlmcl9nZW5vKSAlPiUgCiAgcnN0YXRpeDo6YWRqdXN0X3B2YWx1ZSggbWV0aG9kID0gIkJIIikgJT4lCiAgcnN0YXRpeDo6YWRkX3NpZ25pZmljYW5jZSgicC5hZGoiKSAlPiUgCiAgdW5ncm91cCgpIC0+IGdzdmFfcm5hX2FvdgoKZ3N2YV9ybmFfcmVzdWx0cyAlPiUgCiAgZ3JvdXBfYnkoQ2F0ZWdvcnkpICU+JSAKICByc3RhdGl4Ojp0dWtleV9oc2QoIEVucmljaG1lbnRfU2NvcmUgfiBzZXgrbGlmcl9nZW5vK3NleDpsaWZyX2dlbm8pICU+JSAKICB1bmdyb3VwKCkgJT4lIAogIGFzX3RpYmJsZSgpICU+JSAKICBsZWZ0X2pvaW4oIGdvYW5ub3Rfd2RlZiwgYnkgPSBjKCJDYXRlZ29yeSIgPSAiR09JRCIpKSAtPiBnc3ZhX3JuYV90dWtleQoKZ3N2YV9ybmFfYW92ICU+JSAKICBhc190aWJibGUoKSAlPiUgCiAgZmlsdGVyKCBwLmFkai5zaWduaWYgIT0gIm5zIiApIC0+IHNpZ25pZl9lZmZfdGVybXNfcm5hCgpnc3ZhX3JuYV90dWtleSAlPiUgCiAgZmlsdGVyKCBwLmFkaiA8IDAuMDUpICU+JSAKICBpbm5lcl9qb2luKCAuLCBzZWxlY3QoIHNpZ25pZl9lZmZfdGVybXNfcm5hLCBDYXRlZ29yeSwgdGVybSA9IEVmZmVjdCkpIC0+IHNpZ25pZl9yZXN1bHRzX3R1a2V5X3JuYQoKYGBgCgoKYGBge3IgRmlndXJlMURfcHJlcH0KCkZpZ3VyZTFkX2RhdGEgPC0gZ3N2YV9yZXN1bHRzICU+JQogIGZpbHRlciggQ2F0ZWdvcnkgJWluJSBjKCJHTzowMDA2MzA2IiwgIyBETkEgbWV0aHlsYXRpb24KICAgICAgICAgICAgICAgICAgICAgICAgICAiR086MDAwNjMzOCIsICMgQ2hyb21hdGluIHJlbW9kZWxpbmcKICAgICAgICAgICAgICAgICAgICAgICAgICAiR086MDA0MjI1NCIgIyBSaWJvc29tZSBiaW9nZW5lc2lzCiAgICAgICAgICAgICAgICAgICAgICAgICAgKSkgJT4lCiAgbGVmdF9qb2luKCBzZWxlY3QoZ29hbm5vdF93ZGVmLCBDYXRlZ29yeSA9IEdPSUQsIFRFUk0pKSAlPiUgCiAgc2VsZWN0KCBDYXRlZ29yeSwgVEVSTSwgc2FtcGxlaWQsIEVucmljaG1lbnRfU2NvcmUsIHNleCwgbGlmcl9nZW5vKSAlPiUgCiAgbGVmdF9qb2luKAogICAgc2lnbmlmX3Jlc3VsdHNfdHVrZXkgJT4lIAogICAgICBmaWx0ZXIoIHRlcm0gPT0ic2V4IikgJT4lIAogICAgICBzZWxlY3QoQ2F0ZWdvcnksIHAuYWRqLCBwLmFkai5zaWduaWYgKQogICkgJT4lIAogIHJiaW5kKAogICAgICAgZ3N2YV9yZXN1bHRzICU+JSAgCiAgICAgICAgIGZpbHRlciggQ2F0ZWdvcnkgPT0gIkdPOjAwMDY0NzEiKSAlPiUgICMgcHJvdGVpbiBBRFAtcmlib3N5bGF0aW9uCiAgICAgICAgIGxlZnRfam9pbiggc2VsZWN0KGdvYW5ub3Rfd2RlZiwgQ2F0ZWdvcnkgPSBHT0lELCBURVJNKSkgJT4lIAogICAgICAgICBzZWxlY3QoIENhdGVnb3J5LCBURVJNLCBzYW1wbGVpZCwgRW5yaWNobWVudF9TY29yZSwgc2V4LCBsaWZyX2dlbm8pICU+JSAKICAgICAgICAgbGVmdF9qb2luKAogICAgICAgICAgIHNpZ25pZl9yZXN1bHRzX3R1a2V5ICU+JSAKICAgICAgICAgICAgIGZpbHRlciggdGVybSA9PSJsaWZyX2dlbm8iKSAlPiUgCiAgICAgICAgICAgICBzZWxlY3QoQ2F0ZWdvcnksIHAuYWRqLCBwLmFkai5zaWduaWYgKQogICAgICAgICAgICkKICAgICAgICkgJT4lIAogIG11dGF0ZSggRW5yaWNobWVudF9TY29yZSA9IHJvdW5kKEVucmljaG1lbnRfU2NvcmUsIDIpKSAlPiUgCiAgc2VsZWN0KCBgR08gSURgID0gQ2F0ZWdvcnksIAogICAgICAgICAgYEdPIFRlcm1gPVRFUk0sIAogICAgICAgICAgU2FtcGxlID0gc2FtcGxlaWQsIAogICAgICAgICAgYEVucmljaG1lbnQgU2NvcmVgPUVucmljaG1lbnRfU2NvcmUsIAogICAgICAgICAgU2V4ID0gc2V4LCAKICAgICAgICAgIGBMaWZyIGdlbm90eXBlYD1saWZyX2dlbm8sIAogICAgICAgICAgYFNpZ25pZmljYW5jZWA9cC5hZGouc2lnbmlmKQoKYGBgCgoKYGBge3IgRmlndXJlMURfcGxvdCwgZmlnLndpZHRoPTE2LCBmaWcuaGVpZ2h0PTQsIGZpZy5jYXA9IkZpZ3VyZSAxRDogRW5yaWNobWVudCBzY29yZXMgb2J0YWluZWQgZnJvbSBHU1ZBIGZvciBHZW5lIE9udG9sb2d5IEJpb2xvZ2ljYWwgUHJvY2Vzc2VzIChHTzpCUCkgc2hvd2luZyBzaWduaWZpY2FudCBkaWZmZXJlbmNlcyBiZXR3ZWVuIG1FU0NzIHdpdGggZGlmZmVyZW50IHNleGVzIGFuZCBnZW5vdHlwZXMgYXQgdGhlIExpZnIgbG9jdXMgYXJlIHBsb3R0ZWQuIEdPOkJQIEROQSBtZXRoeWxhdGlvbiwgY2hyb21hdGluIHJlbW9kZWxpbmcgYW5kIHJpYm9zb21lIGJpb2dlbmVzaXMgc2hvdyBzaWduaWZpY2FudGx5IGhpZ2hlciBlbnJpY2htZW50IGluIG1hbGVzIGluIGNvbXBhcmlzb24gdG8gZmVtYWxlcyBhbmQsIHByb3RlaW4gQURQLXJpYm9zeWxhdGlvbiBzaG93cyBzaWduaWZpY2FudGx5IGhpZ2hlciBlbnJpY2htZW50IGluIG1FU0NzIHdpdGggYXQgbGVhc3Qgb25lIGNvcHkgb2YgdGhlIHJlZmVyZW5jZSBhbGxlbGUgaW4gY29tcGFyaXNvbiB0byBvbmVzIGNhcnJ5aW5nIHR3byBjb3BpZXMgb2YgdGhlIGFsdGVybmF0aXZlIGFsbGVsZSBhdCB0aGUgKkxpZnIqIGxvY3VzICh0d28td2F5IGFub3ZhIGZvbGxvd2VkIGJ5IFR1a2V54oCZcyBIU0QsIGAqOiBwIHZhbHVlIDwgMC4wNSwgKioqKjogcCB2YWx1ZSA8IDAuMDAwMDVgKS4ifQoKCkZpZ3VyZTFkX2RhdGEgJT4lIAogIGdncGxvdCgpKwogIGFlcyggeCA9IFNleCwKICAgICAgIHkgPSBgRW5yaWNobWVudCBTY29yZWAsCiAgICAgICBjb2wgPSBTZXgpKwogIGdlb21fYm94cGxvdCh3aWR0aCA9MC4yLCBzaXplID0gMS4xKSsKICAjZ2VvbV9qaXR0ZXIoKSsKICAjZ2VvbV9iZWVzd2FybShhZXMoY29sID0gc2V4KSkrCiAgdGhlbWVfcHViY2xlYW4oYmFzZV9zaXplID0gMTYpKwogIHN0YXRfcHZhbHVlX21hbnVhbCggZmlsdGVyKHNpZ25pZl9yZXN1bHRzX3R1a2V5LENhdGVnb3J5ICA9PSAiR086MDAwNjMwNiIsIHRlcm0gPT0gInNleCIpLAogICAgICAgICAgICAgICAgICAgICAgbGFiZWwgPSAie3AuYWRqLnNpZ25pZn0iLAogICAgICAgICAgICAgICAgICAgICAgeS5wb3NpdGlvbiA9IDAuODUpKwogIGNvbG9yX3BhbGV0dGUoIm5wZyIpKwogIHlsYWIoIkVucmljaG1lbnQgU2NvcmUiKSsKICBnZ3RpdGxlKCJETkEgTWV0aHlsYXRpb24iKSsKICB4bGFiKCIiKSsKICB5bGltKC0xLDEpKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxOCksCiAgICAgICAgYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE4KSwKICAgICAgICBheGlzLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPTE4KSwKICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPTE4LCBoanVzdCA9IDAuNSkpIC0+IHBfbWV0CgpGaWd1cmUxZF9kYXRhICU+JSAKICBnZ3Bsb3QoKSsKICBhZXMoIHggPSBTZXgsCiAgICAgICB5ID0gYEVucmljaG1lbnQgU2NvcmVgLAogICAgICAgY29sID0gU2V4KSsKICBnZW9tX2JveHBsb3Qod2lkdGggPTAuMiwgc2l6ZSA9IDEuMSkrCiAgI2dlb21faml0dGVyKCkrCiAgI2dlb21fYmVlc3dhcm0oYWVzKGNvbCA9IHNleCkpKwogIHRoZW1lX3B1YmNsZWFuKGJhc2Vfc2l6ZSA9IDE2KSsKICBzdGF0X3B2YWx1ZV9tYW51YWwoIGZpbHRlcihzaWduaWZfcmVzdWx0c190dWtleSxDYXRlZ29yeSAgPT0gIkdPOjAwMDYzMzgiLCB0ZXJtID09ICJzZXgiKSwKICAgICAgICAgICAgICAgICAgICAgIGxhYmVsID0gIntwLmFkai5zaWduaWZ9IiwKICAgICAgICAgICAgICAgICAgICAgIHkucG9zaXRpb24gPSAwLjg1KSsKICBjb2xvcl9wYWxldHRlKCJucGciKSsKICB5bGFiKCJFbnJpY2htZW50IFNjb3JlIikrCiAgZ2d0aXRsZSgiQ2hyb21hdGluIHJlbW9kZWxpbmciKSsKICB4bGFiKCIiKSsKICB5bGltKC0xLDEpKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxOCksCiAgICAgICAgYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE4KSwKICAgICAgICBheGlzLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPTE4KSwKICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPTE4LCBoanVzdCA9IC41KSkgLT4gcF9jaHJvbQoKRmlndXJlMWRfZGF0YSAlPiUgCiAgZ2dwbG90KCkrCiAgYWVzKCB4ID0gU2V4LAogICAgICAgeSA9IGBFbnJpY2htZW50IFNjb3JlYCwKICAgICAgIGNvbCA9IFNleCkrCiAgZ2VvbV9ib3hwbG90KHdpZHRoID0wLjIsIHNpemUgPSAxLjEpKwogICNnZW9tX2ppdHRlcigpKwogICNnZW9tX2JlZXN3YXJtKGFlcyhjb2wgPSBzZXgpKSsKICB0aGVtZV9wdWJjbGVhbihiYXNlX3NpemUgPSAxNikrCiAgc3RhdF9wdmFsdWVfbWFudWFsKCBmaWx0ZXIoc2lnbmlmX3Jlc3VsdHNfdHVrZXksQ2F0ZWdvcnkgID09ICJHTzowMDQyMjU0IiwgdGVybSA9PSAic2V4IiksCiAgICAgICAgICAgICAgICAgICAgICBsYWJlbCA9ICJ7cC5hZGouc2lnbmlmfSIsCiAgICAgICAgICAgICAgICAgICAgICB5LnBvc2l0aW9uID0gMC44NSkrCiAgY29sb3JfcGFsZXR0ZSgibnBnIikrCiAgeWxhYigiRW5yaWNobWVudCBTY29yZSIpKwogIGdndGl0bGUoIlJpYm9zb21lIGJpb2dlbmVzaXMiKSsKICB4bGFiKCIiKSsKICB5bGltKC0xLDEpKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxOCksCiAgICAgICAgYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE4KSwKICAgICAgICBheGlzLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPTE4KSwKICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPTE4LCBoanVzdCA9IC41KSkgLT4gcF9yaWJvCgpnc3ZhX3Jlc3VsdHMgJT4lCiAgZmlsdGVyKCBDYXRlZ29yeSA9PSAgIkdPOjAwMDY0NzEiKSAlPiUKICBsZWZ0X2pvaW4oIHNlbGVjdChnb2Fubm90X3dkZWYsIENhdGVnb3J5ID0gR09JRCwgVEVSTSkpICU+JSAKICByZW5hbWUoIGBHTyBJRGAgPSBDYXRlZ29yeSwgCiAgICAgICAgICBgR08gVGVybWA9VEVSTSwgCiAgICAgICAgICBTYW1wbGUgPSBzYW1wbGVpZCwgCiAgICAgICAgICBgRW5yaWNobWVudCBTY29yZWA9RW5yaWNobWVudF9TY29yZSwgCiAgICAgICAgICBTZXggPSBzZXgsIAogICAgICAgICAgYExpZnIgZ2Vub3R5cGVgPWxpZnJfZ2VubykgJT4lIAogIGdncGxvdCgpKwogIGFlcyggeCA9IGBMaWZyIGdlbm90eXBlYCwKICAgICAgIHkgPSAgYEVucmljaG1lbnQgU2NvcmVgLAogICAgICAgY29sID0gYExpZnIgZ2Vub3R5cGVgKSsKICBnZW9tX2JveHBsb3Qod2lkdGggPTAuMiwgc2l6ZSA9IDEuMSkrCiAgI2dlb21faml0dGVyKCkrCiAgI2dlb21fYmVlc3dhcm0oYWVzKGNvbCA9IHNleCkpKwogIHRoZW1lX3B1YmNsZWFuKGJhc2Vfc2l6ZSA9IDE2KSsKICBzdGF0X3B2YWx1ZV9tYW51YWwoIGZpbHRlcihzaWduaWZfcmVzdWx0c190dWtleSxDYXRlZ29yeSAgPT0gIkdPOjAwMDY0NzEiLCB0ZXJtID09ICJsaWZyX2dlbm8iKSwKICAgICAgICAgICAgICAgICAgICAgIGxhYmVsID0gIntwLmFkai5zaWduaWZ9IiwKICAgICAgICAgICAgICAgICAgICAgIHkucG9zaXRpb24gPSBjKDAuODUsIDAuOTUpKSsKICBjb2xvcl9wYWxldHRlKCJEYXJrMiIpKwogIHlsYWIoIkVucmljaG1lbnQgU2NvcmUiKSsKICBnZ3RpdGxlKCJQcm90ZWluIEFEUC1yaWJvc3lsYXRpb24iKSsKICB4bGFiKCIiKSsKICBsYWJzKGNvbCA9IkxJRlIiKSsKICB5bGltKC0xLDEpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTgpLAogICAgICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxOCksCiAgICAgICAgYXhpcy50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0xOCksCiAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0xOCwgaGp1c3QgPSAuNSkpIC0+IHBfYWRwCgpsZWZ0IDwtIGdnYXJyYW5nZShwX21ldCxwX2Nocm9tLCBwX3JpYm8sIAogICAgICAgICAgICAgICAgICBjb21tb24ubGVnZW5kID0gVFJVRSwgCiAgICAgICAgICAgICAgICAgIG5yb3cgPSAxLAogICAgICAgICAgICAgICAgICBuY29sID0gMywgCiAgICAgICAgICAgICAgICAgIGxlZ2VuZCA9ICJub25lIikKCmdnYXJyYW5nZShsZWZ0LCBwX2FkcCwgCiAgICAgICAgICBucm93PTEsIAogICAgICAgICAgd2lkdGhzID0gYyguOCwwLjQpICwgCiAgICAgICAgICBsYWJlbHMgPSBjKCJEIiksIAogICAgICAgICAgZm9udC5sYWJlbCA9IGxpc3QoIHNpemUgPSAyMCkpCgoKYGBgCgo8YnI+CgpUaGUgZGF0YSB1c2VkIGluIHBsb3R0aW5nIEZpZ3VyZTFEIGNhbiBiZSBkb3dubG9hZGVkIHVzaW5nIHRoZSBsaW5rIGJlbG93LgoKYGBge3IgRmlndXJlMURfZGF0YSwgZmlnLmNhcD0iRGF0YSB1c2VkIHRvIGdlbmVyYXRlIEZpZ3VyZSAxRC4ifQoKbGlzdChGaWd1cmUxZF9kYXRhKSAlPiUgCiAgZG93bmxvYWR0aGlzOjpkb3dubG9hZF90aGlzKAogICAgb3V0cHV0X25hbWUgPSAiRmlndXJlMUQgZGF0YSIsCiAgICBvdXRwdXRfZXh0ZW5zaW9uID0gIi54bHN4IiwKICAgIGJ1dHRvbl9sYWJlbCA9ICJEb3dubG9hZCBGaWd1cmUxRCBkYXRhIGFzIHhsc3giLAogICAgYnV0dG9uX3R5cGUgPSAicHJpbWFyeSIsCiAgICBoYXNfaWNvbiA9IFRSVUUsCiAgICBpY29uID0gImZhIGZhLXNhdmUiCiAgKQoKYGBgCgo8YnI+CgojIyMjIFRhYmxlIFMzOiBHZW5lIFNldCBWYXJpYXRpb24gQW5hbHlzaXMgcmVzdWx0cy4gCgpCaW9sb2dpY2FsIHByb2Nlc3NlcyBhbmQgcHJvdGVpbiBjb21wbGV4ZXMgdGhhdCBzaG93IHNpZ25pZmljYW50IGRpZmZlcmVuY2VzIGJldHdlZW4gZXhwZXJpbWVudGFsIGdyb3VwcyAoc2V4LCAqTGlmciogZ2Vub3R5cGUsIG9yIHRoZWlyIGludGVyYWN0aW9uKSBpbiBHU1ZBIGVucmljaG1lbnQgc2NvcmVzIG9idGFpbmVkIGZyb20gcHJvdGVpbiBvciB0cmFuc2NyaXB0IGFidW5kYW5jZSBhcmUgbGlzdGVkLiBUaGUgc291cmNlIG9mIHRoZSBzaWduaWZpY2FudCBlZmZlY3QgKHNleCwgKkxpZnIqIGdlbm90eXBlIG9yIHRoZWlyIGludGVyYWN0aW9uKSBhcyB3ZWxsIGFzIHRoZSB0d28gZ3JvdXBzIGJlaW5nIGNvbXBhcmVkIGlzIGluY2x1ZGVkIHdpdGggdGhlIFR1a2V5J3MgSFNEIGVzdGltYXRlIGFuZCB0aGUgYWRqdXN0ZWQgcC12YWx1ZSBmb3IgZWFjaCB0ZXJtLiAKCgpgYGB7ciBUYWJsZVMzX2dlbmVyYXRlLCB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQoKc2lnbmlmX3Jlc3VsdHNfdHVrZXkgJT4lIAogICNsZWZ0X2pvaW4oIC4sIGdvYW5ub3Rfd2RlZiAlPiUgIHNlbGVjdChURVJNLCBHT0lEKSAlPiUgZGlzdGluY3QoKSkgJT4lIAogIHNlbGVjdChFZmZlY3Q9IHRlcm0sIENhdGVnb3J5LCBURVJNLGdyb3VwMSwgZ3JvdXAyLCBlc3RpbWF0ZSxwLmFkaikgJT4lIAogIGRpc3RpbmN0KCkgJT4lIAogIG11dGF0ZSggZXN0aW1hdGU9IHJvdW5kKGVzdGltYXRlLDIpLAogICAgICAgICAgVEVSTSA9IGlmZWxzZSggQ2F0ZWdvcnkgJWluJSBnZW5lc19mb3JfY29tcGxleF9nc3ZhJGBDb21wbGV4IE5hbWVgLCAiUHJvdGVpbiBDb21wbGV4IiwgVEVSTSkpICU+JSAKICBtdXRhdGUoIAogICAgdGVtcCA9IFRFUk0sCiAgICBURVJNID0gaWZlbHNlKCBURVJNID09IlByb3RlaW4gQ29tcGxleCIgJiAhaXMubmEoVEVSTSksIENhdGVnb3J5LCBURVJNICksCiAgICBDYXRlZ29yeSA9IGlmZWxzZSggdGVtcCA9PSAiUHJvdGVpbiBDb21wbGV4IiAmICFpcy5uYShURVJNKSwgdGVtcCwgQ2F0ZWdvcnkpCiAgICAgICAgICApICU+JSAgCiAgYXJyYW5nZShlc3RpbWF0ZSkgJT4lIAogIHNlbGVjdCggCiAgICBFZmZlY3QsIAogICAgYFRlcm0gSURgID0gQ2F0ZWdvcnksCiAgICBgVGVybSBOYW1lYCA9IFRFUk0sCiAgICBgR3JvdXAgMWA9IGdyb3VwMSwKICAgIGBHcm91cCAyYD0gZ3JvdXAyLAogICAgYFR1a2V5J3MgSFNEIGVzdGltYXRlYCA9IGVzdGltYXRlLCAKICAgIGBBZGp1c3RlZCBwLXZhbHVlYCA9IHAuYWRqCiAgICApIC0+IHRhYmxlczNfc2hlZXQxCgoKc2lnbmlmX3Jlc3VsdHNfdHVrZXlfcm5hICU+JQogICNsZWZ0X2pvaW4oIC4sIGdvYW5ub3Rfd2RlZiAlPiUgIHNlbGVjdChURVJNLCBHT0lEKSAlPiUgZGlzdGluY3QoKSkgJT4lIAogIHNlbGVjdChFZmZlY3Q9IHRlcm0sIENhdGVnb3J5LCBURVJNLGdyb3VwMSwgZ3JvdXAyLCBlc3RpbWF0ZSxwLmFkaikgJT4lIAogIGRpc3RpbmN0KCkgJT4lIAogIG11dGF0ZSggZXN0aW1hdGU9IHJvdW5kKGVzdGltYXRlLDIpLAogICAgICAgICAgVEVSTSA9IGlmZWxzZSggQ2F0ZWdvcnkgJWluJSBnZW5lc19mb3JfY29tcGxleF9nc3ZhJGBDb21wbGV4IE5hbWVgLCAiUHJvdGVpbiBDb21wbGV4IiwgVEVSTSkpICU+JSAKICBtdXRhdGUoIAogICAgdGVtcCA9IFRFUk0sCiAgICBURVJNID0gaWZlbHNlKCBURVJNID09IlByb3RlaW4gQ29tcGxleCIgJiAhaXMubmEoVEVSTSksIENhdGVnb3J5LCBURVJNICksCiAgICBDYXRlZ29yeSA9IGlmZWxzZSggdGVtcCA9PSAiUHJvdGVpbiBDb21wbGV4IiAmICFpcy5uYShURVJNKSwgdGVtcCwgQ2F0ZWdvcnkpCiAgICAgICAgICApICU+JSAKICBhcnJhbmdlKGVzdGltYXRlKSAlPiUgCiAgc2VsZWN0KCAKICAgIEVmZmVjdCwgCiAgICBgVGVybSBJRGAgPSBDYXRlZ29yeSwKICAgIGBUZXJtIE5hbWVgID0gVEVSTSwKICAgIGBHcm91cCAxYD0gZ3JvdXAxLAogICAgYEdyb3VwIDJgPSBncm91cDIsCiAgICBgVHVrZXkncyBIU0QgZXN0aW1hdGVgID0gZXN0aW1hdGUsIAogICAgYEFkanVzdGVkIHAtdmFsdWVgID0gcC5hZGoKICAgICkgLT4gdGFibGVzM19zaGVldDIKCiAgCmBgYAoKCmBgYHtyIFRhYmxlUzNfZGlzcGxheSwgZWNobz1GQUxTRX0KCiMgCiMgd3JpdGV4bDo6d3JpdGVfeGxzeCggbGlzdCggR1NWQV9wcm90ZWluID0gdGFibGVzM19zaGVldDEsCiMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBHU1ZBX3RyYW5zY3JpcHQgPSB0YWJsZXMzX3NoZWV0MiksCiMgICAgICAgICAgICAgICAgICAgICBwYXRoID0gaGVyZSgiVGFibGVTM19HU1ZBX3Jlc3VsdHMueGxzeCIpLAojICAgICAgICAgICAgICAgICAgICAgY29sX25hbWVzID0gVFJVRSwKIyAgICAgICAgICAgICAgICAgICAgIGZvcm1hdF9oZWFkZXJzID0gVFJVRQojICAgICAgICAgICAgICAgICAgICAgKQoKCiMgeGZ1bjo6ZW1iZWRfZmlsZShoZXJlKCJUYWJsZV9TMy54bHN4IikpCgpkb3dubG9hZF9maWxlKAogIHBhdGggPSBoZXJlKCJUYWJsZV9TMy54bHN4IiksCiAgb3V0cHV0X25hbWUgPSAiVGFibGVfUzMiLAogIGJ1dHRvbl9sYWJlbCA9ICJEb3dubG9hZCBUYWJsZV9TMy54bHN4IiwKICBidXR0b25fdHlwZSA9ICJwcmltYXJ5IiwKICBoYXNfaWNvbiA9IFRSVUUsCiAgaWNvbiA9ICJmYSBmYS1zYXZlIiwKICBzZWxmX2NvbnRhaW5lZCA9IEZBTFNFCikKCmBgYAoKPGJyPgoKIyMjIyBPdmVyLXJlcHJlc2VudGF0aW9uIGFuYWx5c2lzIGluIHByb3RlaW5zIHdpdGggaGlnaCBhbmQgbG93IHZhcmlhdGlvbiBpbiBhYnVuZGFuY2UKCmBgYHtyIE9SQV92YXJfcHJvdHMsIGZpZy5jYXA9Ik92ZXItcmVwcmVzZW50ZWQgYmlvbG9naWNhbCBwcm9jZXNzZXMgYW5kIHBhdGh3YXlzIGluIHByb3RlaW5zIHdpdGggaGlnaCAodG9wIDV0aCBwZXJjZW50aWxlKSBhbmQgbG93IHZhcmlhdGlvbiAoYm90dG9tIDV0aCBwZXJjZW50aWxlKS4iLCBjYWNoZSA9IFRSVUV9Cgp2YXJfcHJvdCA8LSBleHByLmVzY19wcm90ICU+JQogIGFzX3RpYmJsZSguKSAlPiUKICBzdW1tYXJpc2VfYWxsKGxpc3QofiB2YXIoLiwgbmEucm0gPSBUKSkpICU+JSAKICBwaXZvdF9sb25nZXIoIGFsbC5wcm90cyRwcm90ZWluX2lkLAogICAgICAgICAgICAgICAgbmFtZXNfdG8gPSAicHJvdGVpbl9pZCIsCiAgICAgICAgICAgICAgICB2YWx1ZXNfdG8gPSJ2YXIiKSAKCmhpZ2gudmFyLnByb3RzIDwtIHZhcl9wcm90ICU+JSAgCiAgZmlsdGVyKCB2YXIgPj0gcXVhbnRpbGUodmFyLCAwLjk1KSkgJT4lIAogIGxlZnRfam9pbiggYWxsLnByb3RzICU+JSAgCiAgICAgICAgICAgICAgIHNlbGVjdCggcHJvdGVpbl9pZCwgbWdpX3N5bWJvbCkpCgpsb3cudmFyLnByb3RzIDwtIHZhcl9wcm90ICU+JSAKICBmaWx0ZXIoIHZhciA8PSBxdWFudGlsZSh2YXIsIDAuMDUpKSU+JSAKICBsZWZ0X2pvaW4oIGFsbC5wcm90cyAlPiUgIAogICAgICAgICAgICAgICBzZWxlY3QoIHByb3RlaW5faWQsIG1naV9zeW1ib2wpKQoKZy5oaWdoLnZhciA8LSBnb3N0KAogIHF1ZXJ5ID0gaGlnaC52YXIucHJvdHMkbWdpX3N5bWJvbCwKICBvcmdhbmlzbSA9ICJtbXVzY3VsdXMiLAogIGRvbWFpbl9zY29wZSA9ICJjdXN0b20iLAogIGN1c3RvbV9iZyA9IGFsbC5wcm90cyRtZ2lfc3ltYm9sLAogIGV2Y29kZXMgPSBUUlVFLAogIGNvcnJlY3Rpb25fbWV0aG9kID0gImZkciIKKQpnLmhpZ2gudmFyJHJlc3VsdCA8LSBnLmhpZ2gudmFyJHJlc3VsdCAlPiUgZmlsdGVyKHRlcm1fc2l6ZSA8IDYwMCkKCmcubG93LnZhciA8LSBnb3N0KAogIHF1ZXJ5ID0gbG93LnZhci5wcm90cyRtZ2lfc3ltYm9sLAogIG9yZ2FuaXNtID0gIm1tdXNjdWx1cyIsCiAgZG9tYWluX3Njb3BlID0gImN1c3RvbSIsCiAgY3VzdG9tX2JnID0gYWxsLnByb3RzJG1naV9zeW1ib2wsCiAgZXZjb2RlcyA9IFRSVUUsCiAgY29ycmVjdGlvbl9tZXRob2QgPSAiZmRyIgopCmcubG93LnZhciRyZXN1bHQgPC0gZy5sb3cudmFyJHJlc3VsdCAlPiUgZmlsdGVyKHRlcm1fc2l6ZSA8IDYwMCkKCmcuaGlnaC52YXIkcmVzdWx0ICU+JSAKICBtdXRhdGUoIGBHZW5lIFNldGAgPSAiSGlnaCB2YXJpYXRpb24iKSAlPiUgCiAgc2VsZWN0KGBHZW5lIFNldGAsIGBUZXJtIE5hbWVgID0gdGVybV9uYW1lLCBzb3VyY2UsIEZEUiA9IHBfdmFsdWUsIGBUZXJtIHNpemVgID0gdGVybV9zaXplLCBJbnRlcnNlY3Rpb24gPSBpbnRlcnNlY3Rpb25fc2l6ZSx0ZXJtX2lkKSAgJT4lIAogIHJiaW5kKAogICAgZy5sb3cudmFyJHJlc3VsdCAlPiUKICAgICAgbXV0YXRlKCBgR2VuZSBTZXRgID0gIkxvdyB2YXJpYXRpb24iKSAlPiUgCiAgICAgICBzZWxlY3QoYEdlbmUgU2V0YCwgYFRlcm0gTmFtZWAgPSB0ZXJtX25hbWUsIHNvdXJjZSwgRkRSID0gcF92YWx1ZSwgYFRlcm0gc2l6ZWAgPSB0ZXJtX3NpemUsIEludGVyc2VjdGlvbiA9IGludGVyc2VjdGlvbl9zaXplLCB0ZXJtX2lkKSAKICAgICkgJT4lIAogIHNlbGVjdCgKICAgICAgICAgYEdlbmUgU2V0YCwgCiAgICBgRGF0YSBzb3VyY2VgID0gc291cmNlLAogICAgYFRlcm0gSURgID0gdGVybV9pZCwKICAgIGBUZXJtIE5hbWVgICwgCiAgICBgVGVybSBzaXplYCAsIAogICAgYCMgb2YgaW50ZXJzZWN0aW5nIHByb3RlaW5zYCA9IEludGVyc2VjdGlvbiwKICAgICBGRFIgCiAgICApICU+JSAKICBtdXRhdGVfaWYoIGlzLm51bWVyaWMsIGZvcm1hdEMsIGRpZ2l0cyA9MikgJT4lIAogIGNyZWF0ZV9kdCgpCgpgYGAKCjxicj4KCiMjIyMgRmlndXJlIFMxRi1HCgpgYGB7ciBGaWd1cmVTMUZfRywgZmlnLmNhcCA9IkZpZ3VyZVMxOiAoRikgTWVhbiBhYnVuZGFuY2UgYW5kIHZhcmlhbmNlIHBsb3R0ZWQgZm9yIGFsbCBwcm90ZWlucyAoZ3JheSkgd2l0aCBwcm90ZWlucyBpZGVudGlmaWVkIGFzIHBhcnQgb2YgYEV4dHJhY2VsbHVsYXIgcmVnaW9uYCBhbmQgYEVDTSBwcm90ZWluYCBHTyBUZXJtcyBpbiBtb3N0IHZhcmlhYmxlIHByb3RlaW5zICh0b3AgNXRoIHBlcmNlbnRpbGUgJUNWKSwgaW4gb3ZlcnJlcHJlc2VudGF0aW9uIGFuYWx5c2lzLCBoaWdobGlnaHRlZCBpbiBibHVlLiAoRykgTWVhbiBhYnVuZGFuY2UgYW5kIHZhcmlhbmNlIHBsb3R0ZWQgZm9yIGFsbCBwcm90ZWlucyB3aXRoIHByb3RlaW5zIGlkZW50aWZpZWQgYXMgYFJFWDEgVGFyZ2V0YCBpbiBUUkFOU0ZBQyBkYXRhYmFzZSBpbiBsZWFzdCB2YXJpYWJsZSBwcm90ZWlucyAoYm90dG9tIDV0aCBwZXJjZW50aWxlICVDViksIGluIG92ZXJyZXByZXNlbnRhdGlvbiBhbmFseXNpcywgaGlnaGxpZ2h0ZWQgaW4gYmx1ZSBhbmQgUkVYMSAoWmZwNDIpIGhpZ2hsaWdodGVkIGluIHB1cnBsZS4iLCBmaWcud2lkdGg9MTAsIGZpZy5oZWlnaHQ9NX0KCiMgZ2V0IHByb3RlaW5zIGlkZW50aWZpZWQgYXMgcGFydCBvZiAiZXh0cmFjZWxsdWxhciByZWdpb24iCmVjbV9nZW5lcyA8LSB0aWJibGUobWdpX3N5bWJvbCA9IHVubGlzdChzdHJfc3BsaXQoKGcuaGlnaC52YXIkcmVzdWx0ICU+JSBmaWx0ZXIodGVybV9uYW1lICVpbiUgYygiZXh0cmFjZWxsdWxhciByZWdpb24iLCAiZXh0cmFjZWxsdWxhciBtYXRyaXgiKSkpJGludGVyc2VjdGlvbiwgIiwiKSkpICU+JQogIGxlZnRfam9pbiguLCBhbGwucHJvdHMpCgojIGdldCBwcm90ZWlucyBpZGVudGlmaWVkIGFzIFJFWDEgdGFyZ2V0cyAKcmV4MS5nZW5lcyA8LSB0aWJibGUobWdpX3N5bWJvbCA9IHVubGlzdChzdHJfc3BsaXQoKGcubG93LnZhciRyZXN1bHQgJT4lIGZpbHRlcihzb3VyY2UgPT0gIlRGIikpJGludGVyc2VjdGlvblsxXSwgIiwiKSkpICU+JQogIGxlZnRfam9pbiguLCBhbGwucHJvdHMpCgojIGdldCB2YXJpYW5jZSArIG1lYW4gYnkgcHJvdGVpbiBpbnRvIGEgc2luZ2xlIGRhdGEgZnJhbWUKbWVhbl9wcm90IDwtIGV4cHIuZXNjX3Byb3QgJT4lCiAgYXNfdGliYmxlKC4pICU+JQogIHN1bW1hcmlzZV9hbGwobGlzdCh+IG1lYW4oLiwgbmEucm0gPSBUKSkpICU+JSAKICBwaXZvdF9sb25nZXIoIGFsbC5wcm90cyRwcm90ZWluX2lkLAogICAgICAgICAgICAgICAgbmFtZXNfdG8gPSAicHJvdGVpbl9pZCIsCiAgICAgICAgICAgICAgICB2YWx1ZXNfdG8gPSJtZWFuIikgCgp2YXJfbWVhbl9wcm90IDwtIHZhcl9wcm90ICU+JSAKICBmdWxsX2pvaW4oIG1lYW5fcHJvdCkgJT4lIAogIGxlZnRfam9pbiggYWxsLnByb3RzKQogIAp2YXJfbWVhbl9wcm90ICU+JSAKICBnZ3NjYXR0ZXIoLiwgCiAgICAgICAgICAgIHggPSAibWVhbiIsIAogICAgICAgICAgICB5ID0gInZhciIsIAogICAgICAgICAgICBzaXplID0gMywgCiAgICAgICAgICAgIGFscGhhID0gMC41LAogICAgICAgICAgICBjb2w9ImdyYXkiLAogICAgICAgICAgICB5c2NhbGUgPSAibG9nMTAiLAogICAgICAgICAgICAjeHNjYWxlID0gImxvZzEwIiwKICAgICAgICAgICAgc2hvdy5sZWdlbmQudGV4dCA9IEZBTFNFCiAgICAgICAgICAgICkgKwogIHhsYWIoIk1lYW4gcHJvdGVpbiBhYnVuZGFuY2UiKSArCiAgeWxhYigiVmFyaWFuY2UgaW4gcHJvdGVpbiBhYnVuZGFuY2UiKSArCiAgZ2d0aXRsZSgiUkVYMSBUYXJnZXQgUHJvdGVpbnMiKSsKICB0aGVtZV9wdWJjbGVhbihiYXNlX3NpemUgPSAxOCkgKyAKICBycmVtb3ZlKCJsZWdlbmQiKSArCiAgZ2VvbV9wb2ludCgKICAgIGRhdGEgPSAgIGZpbHRlciggdmFyX21lYW5fcHJvdCwgZW5zZW1ibF9nZW5lX2lkICVpbiUgcmV4MS5nZW5lcyRlbnNlbWJsX2dlbmVfaWQpICwKICAgIGNvbCA9ICJibHVlIiwgYWxwaGEgPSAwLjYsIHNpemUgPSAzKSsKICBnZW9tX3BvaW50KCBkYXRhID0gZmlsdGVyKHZhcl9tZWFuX3Byb3QsIG1naV9zeW1ib2wgPT0gIlpmcDQyIiksIGNvbCA9ICJwdXJwbGUiLCBzaXplID0gNCwgYWxwaGEgPSAxKSsKICBnZW9tX2xhYmVsKCBkYXRhID0gZmlsdGVyKHZhcl9tZWFuX3Byb3QsIG1naV9zeW1ib2wgPT0gIlpmcDQyIikgLCBsYWJlbCA9ICJSZXgxIiwgbnVkZ2VfeCA9IC4yLCBudWRnZV95ID0gLjIpICAtPiBwbG90X3JleDEKCgp2YXJfbWVhbl9wcm90ICU+JSAKICBnZ3NjYXR0ZXIoLiwgCiAgICAgICAgICAgIHkgPSAidmFyIiwgCiAgICAgICAgICAgIHggPSAibWVhbiIsIAogICAgICAgICAgICBzaXplID0gMywgCiAgICAgICAgICAgIGFscGhhID0gMC41LAogICAgICAgICAgICBjb2w9ImdyYXkiLAogICAgICAgICAgICB5c2NhbGUgPSAibG9nMTAiLAogICAgICAgICAgICAjeHNjYWxlID0gImxvZzEwIiwKICAgICAgICAgICAgc2hvdy5sZWdlbmQudGV4dCA9IEZBTFNFCiAgICAgICAgICAgICkgKwogIHlsYWIoIlZhcmlhbmNlIGluIHByb3RlaW4gYWJ1bmRhbmNlIikgKwogIHhsYWIoIk1lYW4gcHJvdGVpbiBhYnVuZGFuY2UiKSArCiAgdGhlbWVfcHViY2xlYW4oYmFzZV9zaXplID0gMTgpICsgCiAgcnJlbW92ZSgibGVnZW5kIikgKwogIGdlb21fcG9pbnQoCiAgICBkYXRhID0gICBmaWx0ZXIoIHZhcl9tZWFuX3Byb3QsIGVuc2VtYmxfZ2VuZV9pZCAlaW4lIGMoZWNtX2dlbmVzJGVuc2VtYmxfZ2VuZV9pZCkpICwKICAgIGNvbCA9ICJibHVlIiwgYWxwaGEgPSAwLjYsIHNpemUgPSAzKSArCiAgZ2d0aXRsZSgiRXh0cmFjZWxsdWxhciBNYXRyaXggUHJvdGVpbnMiKS0+IHBsb3RfZWNtCgpnZ2FycmFuZ2UoIHBsb3RfZWNtLCBwbG90X3JleDEsIG5yb3cgPTEgLAogICAgICAgICAgIGxhYmVscyA9IGMoIkYiLCJHIiksCiAgICAgICAgICBmb250LmxhYmVsID0gbGlzdCggc2l6ZSA9IDIwKQogICAgICAgICkKCgpgYGAK

A work by Selcan Aydin

selcan.aydin@jax.org